Machloket Handling¶
Halachic literature is replete with disputes (machloket) between authorities. Mistaber's multi-world architecture is specifically designed to represent these disputes accurately. This document explains how to identify, encode, and test machloket across the seven Kripke worlds.
Types of Disputes¶
Mechaber vs Rema (Primary Dispute Pattern)¶
The most common machloket pattern: Mechaber (Sefardi) vs Rema (Ashkenazi) on foundational issues.
graph TD
A[Shulchan Aruch Seif] --> B{Rema glosses?}
B -->|Yes - Explicit disagreement| C[Mechaber + Rema worlds<br/>with override]
B -->|Yes - Addition only| D[Mechaber world<br/>Rema inherits + adds]
B -->|No gloss| E[Mechaber world only<br/>All inherit]
When to encode as machloket: - Rema explicitly says "yesh omrim" (some say) differently - Rema adds "v'yeish l'hachmir" (and one should be stringent) - Rema's gloss contradicts Mechaber's ruling - Later poskim document this as a machloket
When NOT to encode as machloket: - Rema adds a case not covered by Mechaber - Rema provides additional detail without disagreement - Rema's silence (implies agreement)
Rishonim Disputes (Pre-SA)¶
Disputes between Rishonim that the Shulchan Aruch resolved:
% SA follows Rambam over Rosh on this point
rule(r_following_rambam).
makor(r_following_rambam, sa("yd:XX:Y")).
makor(r_following_rambam, rambam("hilchot:X:Y")).
% Document the Rishonim machloket in comments
% RISHONIM MACHLOKET:
% Rambam: [Position A]
% Rosh: [Position B]
% SA follows: Rambam
% Reason: Per Beit Yosef...
scope(r_following_rambam, mechaber).
Rishonim Disputes
When encoding SA, follow the SA's resolution. Document alternative Rishonim views in comments for context, but do not create separate worlds for Rishonim.
Acharonim Disputes (Post-SA)¶
Disputes between later authorities about interpreting SA/Rema:
% Taz and Shach disagree on interpretation
% === Following Shach's interpretation (more widely accepted) ===
rule(r_shach_interpretation).
makor(r_shach_interpretation, sa("yd:XX:Y")).
makor(r_shach_interpretation, shach("yd:XX:Z")).
scope(r_shach_interpretation, mechaber).
% === Alternative: Taz interpretation ===
% If Taz's view is followed in specific child worlds, encode there
% See: ashk_ah may follow Taz in some cases
Later Poskim (Child World) Disputes¶
When Mishnah Berurah and Aruch HaShulchan disagree:
% === Mishnah Berurah position ===
rule(r_mb_stricter_view).
makor(r_mb_stricter_view, mishnah_berurah("yd:XX:Y")).
scope(r_mb_stricter_view, ashk_mb).
asserts(ashk_mb, stricter_ruling(X)).
% === Aruch HaShulchan position ===
rule(r_ah_lenient_view).
makor(r_ah_lenient_view, aruch_hashulchan("yd:XX:Y")).
scope(r_ah_lenient_view, ashk_ah).
override(ashk_ah, stricter_ruling(X), lenient_ruling).
asserts(ashk_ah, lenient_ruling(X)).
Override Semantics¶
The override/3 Predicate¶
Syntax: override(World, OverriddenProp, DescriptiveValue)
The third argument is a descriptive value indicating the overriding position, NOT 'invalid' or 'false':
% CORRECT - descriptive values
override(rema, sakana(M), no_sakana) :-
is_dag_chalav_mixture(M).
override(rema, issur(achiila, M, sakana), permitted_eating) :-
is_dag_chalav_mixture(M).
override(ashk_ah, safek_policy(d_rabanan, l_chumra), l_kula) :-
context(normal).
Never Use 'invalid' in Override
How Override Works with Kripke Inheritance¶
graph TD
subgraph "Without Override"
A1[base asserts X] --> B1[mechaber inherits X]
B1 --> C1[sefardi_yo inherits X]
end
subgraph "With Override"
A2[mechaber asserts sakana M] --> B2[sefardi_yo inherits sakana M]
A2 -.->|override| C2[rema: no_sakana M]
C2 --> D2[ashk_mb inherits no_sakana M]
C2 --> E2[ashk_ah inherits no_sakana M]
end
Override Propagation Rules¶
| Scenario | Result |
|---|---|
| Parent asserts X, no override | Child inherits X |
| Parent asserts X, child overrides | Child has override value |
| Grandchild of overriding world | Inherits the override |
| Override in one branch | Other branches unaffected |
% mechaber asserts sakana
asserts(mechaber, sakana(M)) :- is_dag_chalav_mixture(M).
% rema overrides
override(rema, sakana(M), no_sakana) :- is_dag_chalav_mixture(M).
% Inheritance result:
% - sefardi_yo: inherits sakana(M) from mechaber
% - ashk_mb: inherits no_sakana(M) from rema (via override)
% - ashk_ah: inherits no_sakana(M) from rema (via override)
Multi-World Encoding Strategy¶
Step 1: Identify the Dispute¶
Analyze the source to determine:
- Who are the disputants?
- Mechaber vs Rema?
- Shach vs Taz?
-
MB vs AH?
-
What is the nature of disagreement?
- Complete opposition?
- Scope limitation?
-
Stringency level?
-
Which worlds are affected?
- Does it affect all descendants?
- Is it limited to specific traditions?
Step 2: Encode the Base Position¶
Start with the position in the primary world:
% ============================================================
% MACHLOKET: Fish + Dairy
% Mechaber: Forbidden due to sakana
% Rema: Permitted
% ============================================================
% === Mechaber's Position (Primary) ===
rule(r_bb_dag_sakana).
makor(r_bb_dag_sakana, sa("yd:87:3")).
makor(r_bb_dag_sakana, beit_yosef("yd:87")).
scope(r_bb_dag_sakana, mechaber).
asserts(mechaber, sakana(M)) :-
is_dag_chalav_mixture(M).
asserts(mechaber, issur(achiila, M, sakana)) :-
is_dag_chalav_mixture(M).
Step 3: Encode the Override Position¶
Add the overriding position in the appropriate world:
% === Rema's Override Position ===
rule(r_rema_dag_chalav_mutar).
makor(r_rema_dag_chalav_mutar, rema("yd:87:3")).
makor(r_rema_dag_chalav_mutar, taz("yd:87:3")).
makor(r_rema_dag_chalav_mutar, shach("yd:87:5")).
scope(r_rema_dag_chalav_mutar, rema).
% Override the sakana assertion
override(rema, sakana(M), no_sakana) :-
is_dag_chalav_mixture(M).
override(rema, issur(achiila, M, sakana), permitted) :-
is_dag_chalav_mixture(M).
% Explicitly assert the permissive position
asserts(rema, heter(achiila, M)) :-
is_dag_chalav_mixture(M).
asserts(rema, no_sakana(M)) :-
is_dag_chalav_mixture(M).
Step 4: Mark the Machloket¶
Use the machloket/4 predicate to document the dispute:
% Document the machloket
machloket(dag_chalav_sakana, mechaber, rema, M) :-
is_dag_chalav_mixture(M).
Step 5: Verify Child World Inheritance¶
Confirm child worlds inherit correctly:
% === Verification: sefardi_yo ===
% Should inherit sakana from mechaber
% No override in sefardi_yo, so mechaber's position propagates
% === Verification: ashk_mb ===
% Should inherit no_sakana from rema
% No override in ashk_mb, so rema's override propagates
% === Verification: ashk_ah ===
% Should inherit no_sakana from rema
% Also accessible from gra (who also permits)
% No override in ashk_ah, so rema's position propagates
Testing Both Positions¶
Required Tests for Machloket¶
Every machloket encoding requires tests for both positions:
import pytest
from mistaber import query
class TestFishDairyMachloket:
"""Tests for fish+dairy machloket between Mechaber and Rema."""
@pytest.fixture
def fish_dairy_mixture(self):
return """
mixture(m1).
food(salmon). food_type(salmon, dag).
food(cream). food_type(cream, chalav).
contains(m1, salmon). contains(m1, cream).
"""
# === Mechaber Position Tests ===
def test_mechaber_asserts_sakana(self, fish_dairy_mixture):
"""Mechaber holds fish+dairy is sakana."""
result = query(fish_dairy_mixture, world="mechaber")
assert result.holds("sakana(m1)")
def test_mechaber_forbids_eating(self, fish_dairy_mixture):
"""Mechaber forbids eating fish+dairy due to sakana."""
result = query(fish_dairy_mixture, world="mechaber")
assert result.holds("issur(achiila, m1, sakana)")
def test_sefardi_yo_inherits_sakana(self, fish_dairy_mixture):
"""Yalkut Yosef inherits sakana from Mechaber."""
result = query(fish_dairy_mixture, world="sefardi_yo")
assert result.holds("sakana(m1)")
assert result.holds("issur(achiila, m1, sakana)")
# === Rema Position Tests ===
def test_rema_permits_eating(self, fish_dairy_mixture):
"""Rema permits eating fish+dairy."""
result = query(fish_dairy_mixture, world="rema")
assert result.holds("heter(achiila, m1)")
assert not result.holds("sakana(m1)")
def test_rema_asserts_no_sakana(self, fish_dairy_mixture):
"""Rema explicitly holds no sakana."""
result = query(fish_dairy_mixture, world="rema")
assert result.holds("no_sakana(m1)")
def test_ashk_mb_inherits_permission(self, fish_dairy_mixture):
"""Mishnah Berurah inherits permission from Rema."""
result = query(fish_dairy_mixture, world="ashk_mb")
assert result.holds("heter(achiila, m1)")
assert result.holds("no_sakana(m1)")
def test_ashk_ah_inherits_permission(self, fish_dairy_mixture):
"""Aruch HaShulchan inherits permission from Rema."""
result = query(fish_dairy_mixture, world="ashk_ah")
assert result.holds("heter(achiila, m1)")
# === Machloket Detection Test ===
def test_machloket_detected(self, fish_dairy_mixture):
"""The machloket between Mechaber and Rema is detected."""
result = query(fish_dairy_mixture, world="base")
assert result.holds("machloket(dag_chalav_sakana, mechaber, rema, m1)")
Cross-World Comparison Tests¶
def test_cross_world_divergence(fish_dairy_mixture):
"""Verify that worlds diverge correctly on this machloket."""
mechaber_result = query(fish_dairy_mixture, world="mechaber")
rema_result = query(fish_dairy_mixture, world="rema")
# Mechaber and Rema should disagree
assert mechaber_result.holds("sakana(m1)")
assert not rema_result.holds("sakana(m1)")
# Verify they have opposite rulings
assert mechaber_result.holds("issur(achiila, m1, sakana)")
assert rema_result.holds("heter(achiila, m1)")
Edge Cases in Disputes¶
Partial Agreement¶
When authorities agree on principle but differ on application:
% Both agree poultry+dairy is d_rabanan
% But disagree on specific application
% === Shared Agreement ===
% Encode in both worlds explicitly
rule(r_bb_of_drabbanan_mechaber).
scope(r_bb_of_drabbanan_mechaber, mechaber).
asserts(mechaber, issur(achiila, M, d_rabanan)) :-
is_of_chalav_mixture(M).
rule(r_bb_of_drabbanan_rema).
scope(r_bb_of_drabbanan_rema, rema).
asserts(rema, issur(achiila, M, d_rabanan)) :-
is_of_chalav_mixture(M).
% === Disagreement on Application ===
% Mechaber: Specific leniency applies
% Rema: Does not apply
% Encode the disagreement in specific rule
Three-Way Disputes¶
When GRA differs from both Mechaber and Rema:
% === Mechaber's Position ===
rule(r_mechaber_pos).
scope(r_mechaber_pos, mechaber).
asserts(mechaber, position_a(X)).
% === Rema's Position (differs from Mechaber) ===
rule(r_rema_pos).
scope(r_rema_pos, rema).
override(rema, position_a(X), position_b).
asserts(rema, position_b(X)).
% === GRA's Position (differs from both) ===
rule(r_gra_pos).
scope(r_gra_pos, gra).
override(gra, position_a(X), position_c). % Overrides if inherited from base
asserts(gra, position_c(X)).
% === Aruch HaShulchan ===
% AH inherits from both rema AND gra
% Need to resolve which position AH follows
% If AH follows GRA on this:
override(ashk_ah, position_b(X), position_c) :-
follows_gra(ashk_ah, this_topic).
Conditional Machloket¶
When dispute only applies under certain conditions:
% Machloket only applies when hefsed is present
% In normal circumstances, all agree
% === Agreement in Normal Circumstances ===
asserts(mechaber, issur(achiila, M, d_rabanan)) :-
some_mixture(M),
context(ctx_normal).
% Rema inherits (no override needed for normal context)
% === Machloket in Hefsed ===
% Mechaber: Still forbidden
asserts(mechaber, issur(achiila, M, d_rabanan)) :-
some_mixture(M),
context(ctx_hefsed).
% Rema: Permitted due to hefsed
rule(r_rema_hefsed_leniency).
scope(r_rema_hefsed_leniency, rema).
asserts(rema, heter(achiila, M)) :-
some_mixture(M),
context(ctx_hefsed),
has_supporting_opinion(M).
machloket(hefsed_leniency, mechaber, rema, M) :-
some_mixture(M),
context(ctx_hefsed).
Temporal Machloket¶
When practice changed over time:
% Historical: Earlier practice
% Current: Contemporary practice
% === Original Ruling ===
rule(r_original_ruling).
makor(r_original_ruling, sa("yd:XX:Y")).
scope(r_original_ruling, mechaber).
asserts(mechaber, original_practice(X)).
% === Contemporary Override (in child world) ===
rule(r_contemporary_practice).
makor(r_contemporary_practice, yalkut_yosef("yd:XX:Y")).
scope(r_contemporary_practice, sefardi_yo).
% Yalkut Yosef updates the practice
override(sefardi_yo, original_practice(X), contemporary_practice).
asserts(sefardi_yo, contemporary_practice(X)).
% Document this is a temporal change, not disagreement
temporal_change(original_ruling, contemporary_practice, sefardi_yo).
Machloket Documentation Template¶
Use this template for documenting machloket:
% ============================================================
% MACHLOKET: [Topic Name]
% ============================================================
%
% DISPUTANTS:
% - [Authority 1]: [Their position]
% - [Authority 2]: [Their position]
%
% SOURCES:
% - [Authority 1]: [Citation]
% - [Authority 2]: [Citation]
%
% AFFECTED WORLDS:
% - [World 1]: Follows [Authority X]
% - [World 2]: Follows [Authority Y]
%
% NATURE OF DISPUTE:
% [Complete opposition / Scope limitation / Stringency level]
%
% PRACTICAL DIFFERENCE:
% [What changes between the positions]
%
% ============================================================
% [Encoding follows...]
Common Machloket Mistakes¶
Mistake 1: Missing Override for One Branch¶
% WRONG - only encoded mechaber, rema has no override
asserts(mechaber, position_a(X)).
% No rema encoding -> rema incorrectly inherits position_a
% CORRECT - both positions encoded
asserts(mechaber, position_a(X)).
override(rema, position_a(X), position_b).
asserts(rema, position_b(X)).
Mistake 2: Override Without Positive Assertion¶
% WRONG - override without alternative assertion
override(rema, issur(achiila, M, sakana), no_issur).
% What IS permitted? Unclear.
% CORRECT - override with positive assertion
override(rema, issur(achiila, M, sakana), permitted).
asserts(rema, heter(achiila, M)). % Explicit permission
Mistake 3: Encoding Agreement as Machloket¶
% WRONG - no actual disagreement
asserts(mechaber, issur(achiila, M, d_oraita)).
asserts(rema, issur(achiila, M, d_oraita)). % Same thing!
machloket(topic, mechaber, rema, M). % Not a machloket!
% CORRECT - only mechaber needed, rema inherits
asserts(mechaber, issur(achiila, M, d_oraita)).
% No machloket declaration - they agree
Mistake 4: Missing machloket/4 Declaration¶
% WRONG - machloket exists but not declared
asserts(mechaber, sakana(M)).
override(rema, sakana(M), no_sakana).
% No machloket/4 - dispute not discoverable
% CORRECT - machloket declared
asserts(mechaber, sakana(M)).
override(rema, sakana(M), no_sakana).
machloket(dag_chalav_sakana, mechaber, rema, M). % Documented
Related Guidelines¶
- World Scoping - When to use which world
- Halachic Concepts - Authority levels and disputes
- Source Attribution - Citing sources for both positions
- Testing Requirements - Testing both positions