Kripke Implementation¶
This document describes how Mistaber implements Kripke semantics for multi-world halachic reasoning, enabling representation of different halachic authorities as "possible worlds" with inheritance and override mechanisms.
Overview¶
Kripke semantics provides the formal framework for: - Representing multiple halachic authorities (Mechaber, Rema, GRA, etc.) - Modeling inheritance relationships between authorities - Handling disputes (machloket) through world comparison - Supporting diamond inheritance patterns - Enabling psak (ruling) derivation based on user's tradition
World Declaration in ASP¶
Each halachic authority is declared as a world in ASP:
% mistaber/ontology/worlds/base.lp
world(base).
% mistaber/ontology/worlds/mechaber.lp
world(mechaber).
accessible(mechaber, base).
% mistaber/ontology/worlds/rema.lp
world(rema).
accessible(rema, base).
World Declaration Pattern¶
% 1. Declare the world exists
world(world_name).
% 2. Declare accessibility (inheritance) from parent(s)
accessible(world_name, parent_world).
% 3. Optionally declare safek policies
safek_policy(world_name, d_oraita, l_chumra).
safek_policy(world_name, d_rabanan, l_kula).
% 4. Include corpus files if needed
#include "../corpus/yd_87/base.lp".
The 7 Worlds and Their Relationships¶
Mistaber includes seven halachic worlds organized in a DAG:
World Hierarchy¶
World Descriptions¶
| World | Authority | Tradition | Parent(s) |
|---|---|---|---|
base |
Shulchan Aruch foundations | Universal | None (root) |
mechaber |
R' Yosef Karo | Sefardi | base |
rema |
R' Moshe Isserles | Ashkenazi | base |
gra |
Vilna Gaon | Litvish | base |
sefardi_yo |
Yalkut Yosef | Sefardi modern | mechaber |
ashk_mb |
Mishnah Berurah | Litvish/Ashkenazi | rema |
ashk_ah |
Aruch Hashulchan | Russian Ashkenazi | rema, gra |
Diamond Inheritance: ashk_ah¶
The ashk_ah world demonstrates multiple inheritance:
% mistaber/ontology/worlds/ashk_ah.lp
world(ashk_ah).
% ashk_ah inherits from BOTH rema AND gra
accessible(ashk_ah, rema).
accessible(ashk_ah, gra).
This models how R' Yechiel Michel Epstein synthesized both traditions.
Accessibility Relation (accessible/2)¶
The accessible/2 predicate defines inheritance relationships:
Meaning: World Child can "see" (inherit from) world Parent.
Frame Properties¶
The accessibility relation has these properties:
| Property | Definition | In Mistaber |
|---|---|---|
| Irreflexive | No accessible(W, W) |
Yes - worlds don't inherit from themselves |
| Transitive | If A→B and B→C then A→C | Yes - via ancestor/2 |
| Antisymmetric | If A→B then not B→A | Yes - enforced by DAG validation |
Transitive Closure¶
The ancestor/2 predicate computes transitive inheritance:
% mistaber/engine/priorities.lp
% Direct parent is ancestor
ancestor(W_child, W_parent) :-
world(W_child),
world(W_parent),
accessible(W_child, W_parent).
% Transitive closure: grandparent and beyond
ancestor(W1, W3) :-
world(W1),
world(W3),
accessible(W1, W2),
ancestor(W2, W3).
Truth Propagation (holds/2)¶
The core of Kripke semantics is truth propagation via holds/2:
% mistaber/ontology/worlds/kripke_rules.lp
% Local assertions hold in their world
holds(Prop, W) :-
asserts(W, Prop),
world(W).
% Inherit from accessible (parent) worlds
holds(Prop, W_child) :-
accessible(W_child, W_parent),
holds(Prop, W_parent),
not overridden(Prop, W_child).
How Truth Flows¶
- Local Assertion: If
asserts(W, Prop), thenholds(Prop, W) - Inheritance: If
holds(Prop, Parent)andaccessible(Child, Parent), thenholds(Prop, Child)unless overridden - Override: If
override(W, Prop, _), then inheritance is blocked
Rule Scoping (scope/2, active_in_world/2)¶
Rules are scoped to specific worlds:
% Rule declaration with scope
rule(r_bb_beheima_achiila).
makor(r_bb_beheima_achiila, sa("yd:87:1")).
madrega(r_bb_beheima_achiila, d_oraita).
scope(r_bb_beheima_achiila, mechaber).
Rule Activation¶
% mistaber/engine/priorities.lp
% A rule is active in a world if directly scoped to that world
active_in_world(R, W) :-
rule(R),
world(W),
scope(R, W),
not overridden_in(R, W).
% A rule is active in a world if scoped to an ancestor and not overridden
active_in_world(R, W) :-
rule(R),
world(W),
scope(R, W_ancestor),
ancestor(W, W_ancestor),
not overridden_in(R, W).
Override Mechanism¶
override/3 Declaration¶
Child worlds can override parent propositions:
% mistaber/ontology/worlds/rema.lp
% Override the Mechaber's sakana ruling for fish + dairy
override(rema, sakana(M), no_sakana) :-
is_dag_chalav_mixture(M).
override(rema, issur(achiila, M, sakana), permitted) :-
is_dag_chalav_mixture(M).
overrides/4 for Rules¶
% Declare that R_child overrides R_parent in world W
overrides(R_child, R_parent, W, Override_type).
% Override types:
% - always: unconditional override
% - condition(C): override only when C holds
Override Logic¶
% mistaber/engine/priorities.lp
% A rule is overridden if another rule overrides it
overridden_in(R, W) :-
rule(R),
world(W),
overrides(R_child, R, W, Override_type),
active_override(R_child, R, W, Override_type).
% Override mechanism for propositions
overridden(Prop, W) :-
override(W, Prop, _).
Diamond Inheritance Handling¶
When a world inherits from multiple parents with conflicting positions, explicit priority resolution is required:
Conflict Detection¶
% mistaber/engine/priorities.lp
% Detect conflict: world inherits conflicting positions
conflict(W, topic(Topic)) :-
world(W),
world(W1),
world(W2),
accessible(W, W1),
accessible(W, W2),
W1 != W2,
active_in_world(R1, W1),
active_in_world(R2, W2),
rule_concludes(R1, position(Topic, Val1)),
rule_concludes(R2, position(Topic, Val2)),
Val1 != Val2,
not priority(W1, W2, W),
not priority(W2, W1, W).
Conflict Resolution via priority/3¶
% Declare that W1 takes precedence over W2 in child world W
priority(W1, W2, W).
% Resolution determines the winning rule
priority_winner(R, W) :-
world(W),
world(W_preferred),
world(W_less),
accessible(W, W_preferred),
accessible(W, W_less),
priority(W_preferred, W_less, W),
active_in_world(R, W_preferred),
rule_concludes(R, position(Topic, _)),
active_in_world(R2, W_less),
rule_concludes(R2, position(Topic, _)),
R != R2.
Interpretation Layer¶
Commentators (Shach, Taz, etc.) are NOT separate worlds. They are interpretation functions that modify rule conditions WITHIN a world:
% mistaber/engine/interpretations.lp
% Commentator declarations
commentator(shach). % Sifsei Kohen
commentator(taz). % Turei Zahav
commentator(pri_megadim). % R' Yosef Teomim
commentator(pri_chadash). % R' Chizkiyah da Silva
% Who interprets whom
interprets(shach, mechaber).
interprets(taz, mechaber).
interprets(pri_megadim, shach).
interprets(pri_megadim, taz).
interprets(pri_chadash, mechaber).
Interpretation Types¶
% Type 1: Adds a condition to a rule
interpretation(Comm, Rule, adds_condition(Cond)) :-
adds_condition(Comm, Rule, Cond).
% Type 2: Removes/relaxes a condition
interpretation(Comm, Rule, removes_condition(Cond)) :-
removes_condition(Comm, Rule, Cond).
% Type 3: Restricts scope
interpretation(Comm, Rule, restricts_to(Scope)) :-
restricts_scope(Comm, Rule, Scope).
% Type 4: Expands scope
interpretation(Comm, Rule, expands_to(Scope)) :-
expands_scope(Comm, Rule, Scope).
Interpretation Precedence¶
% Default precedence (higher number = wins in conflict)
interpretation_precedence(mechaber, taz, 1).
interpretation_precedence(mechaber, shach, 2).
interpretation_precedence(mechaber, pri_chadash, 3).
% Override precedence from config if provided
effective_precedence(Authority, Comm, Prec) :-
config_interp_precedence(Comm, Prec),
interprets(Comm, Authority).
File Organization¶
mistaber/ontology/worlds/
├── base.lp # Root world - common halachic ground
├── mechaber.lp # Sefardi tradition (Shulchan Aruch author)
├── rema.lp # Ashkenazi glosses (disagreements marked)
├── gra.lp # Vilna Gaon (independent Tier 2)
├── ashk_mb.lp # Mishnah Berurah (Litvish)
├── ashk_ah.lp # Aruch Hashulchan (multiple inheritance)
├── sefardi_yo.lp # Yalkut Yosef (follows Mechaber)
└── kripke_rules.lp # Truth propagation and override logic
mistaber/engine/
├── priorities.lp # Rule activation, override, conflict resolution
├── interpretations.lp # Commentator interpretation layer
├── safek.lp # Safek propagation with world awareness
├── preferences.lp # asprin preference specification
└── kripke/ # Python support for world management
├── validation.py # DAG cycle detection
└── worlds.py # WorldManager class
Python Support¶
WorldManager¶
# mistaber/engine/kripke/worlds.py
class WorldManager:
"""Manages the world DAG for Kripke semantics."""
def add_world(
self,
name: str,
parent: Optional[str] = None,
parents: Optional[List[str]] = None
) -> None:
"""Add a world to the DAG."""
def get_parents(self, world: str) -> List[str]:
"""Get direct parents of a world."""
def get_ancestors(self, world: str) -> List[str]:
"""Get all ancestors in BFS order."""
def set_actual_world(self, world: str) -> None:
"""Set the designated actual world."""
WorldDAGValidator¶
# mistaber/engine/kripke/validation.py
class WorldDAGValidator:
"""Validates that world accessibility forms a DAG."""
def validate(self, edges: List[Tuple[str, Optional[str]]]) -> bool:
"""
Validate edges form a DAG.
Uses DFS with white/gray/black coloring.
Raises CyclicWorldError if cycle detected.
"""
Example: Fish + Dairy Machloket¶
The fish + dairy case demonstrates world-based machloket handling:
Mechaber's Position (sakana)¶
% mistaber/ontology/worlds/mechaber.lp
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).
Rema's Position (no sakana)¶
% mistaber/ontology/worlds/rema.lp
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 ruling
override(rema, sakana(M), no_sakana) :-
is_dag_chalav_mixture(M).
override(rema, issur(achiila, M, sakana), permitted) :-
is_dag_chalav_mixture(M).
% Explicit permission
asserts(rema, heter(achiila, M)) :-
is_dag_chalav_mixture(M).
asserts(rema, no_sakana(M)) :-
is_dag_chalav_mixture(M).
% Mark as machloket
machloket(dag_chalav, mechaber, rema, M) :-
is_dag_chalav_mixture(M).
Query Results¶
# Compare across worlds
results = engine.compare(
pattern="holds(issur(achiila, M, Reason), W)",
worlds=["mechaber", "rema"]
)
# mechaber: [{"M": "fish_cream", "Reason": "sakana"}]
# rema: [] (no issur - permitted)
Safek Handling by World¶
Each world can define its own safek policy:
% Base default
safek_policy(base, d_oraita, l_chumra). % Biblical → stringent
safek_policy(base, d_rabanan, l_kula). % Rabbinic → lenient
% Mishnah Berurah is stricter
safek_policy(ashk_mb, d_oraita, l_chumra).
safek_policy(ashk_mb, d_rabanan, l_chumra). % Stricter than default
% Aruch Hashulchan follows standard
safek_policy(ashk_ah, d_oraita, l_chumra).
safek_policy(ashk_ah, d_rabanan, l_kula). % More lenient than MB
Show Directives¶
Key predicates are shown for debugging: