Ontology Structure¶
Overview¶
The Mistaber ontology provides the foundational knowledge for halachic reasoning. It is organized in three layers:
┌─────────────────────────────────────────────────────────────────┐
│ EXTENSIONS LAYER │
│ User-defined concepts, local minhagim, custom foods │
│ Location: mistaber/ontology/extensions/ │
└──────────────────────────────────┬──────────────────────────────┘
│ extends
┌──────────────────────────────────▼──────────────────────────────┐
│ BASE LAYER │
│ Core halachic rules and derived predicates │
│ Location: mistaber/ontology/base/ │
│ • substance.lp - Food type inheritance, mixtures │
│ • madrega.lp - Normative level hierarchy │
│ • context.lp - Situational leniency │
│ • status.lp - Normative statuses │
│ • temporal.lp - Time-based reasoning │
│ • shiur.lp - Measurements and ratios │
│ • issur_types.lp - Prohibition classifications │
└──────────────────────────────────┬──────────────────────────────┘
│ depends on
┌──────────────────────────────────▼──────────────────────────────┐
│ SCHEMA LAYER │
│ Sort declarations, enumerations, integrity constraints │
│ Location: mistaber/ontology/schema/ │
│ • sorts.lp - All type definitions │
│ • constraints.lp - General integrity rules │
│ • disjointness.lp - Mutual exclusivity axioms │
└─────────────────────────────────────────────────────────────────┘
Schema Layer¶
sorts.lp¶
Defines all domain types (sorts) and enumerated values.
Physical Domain Sorts¶
#defined food/1. % Food items
#defined vessel/1. % Cooking vessels (kelim)
#defined mixture/1. % Combined substances
Normative Domain Sorts¶
#defined world/1. % Possible worlds (modal logic)
#defined rule/1. % Halachic rules
#defined posek/1. % Halachic authorities
Food Categories¶
The food classification hierarchy:
maakhal (generic food)
├── basar (meat)
│ ├── beheima (domesticated land animal)
│ ├── chaya (wild land animal)
│ ├── of (poultry)
│ └── dag (fish)
├── chalav (dairy)
└── parve (neutral)
├── mashkeh (liquid)
└── tavlin (spice)
Defined as:
food_category(maakhal).
food_category(basar).
food_category(chalav).
...
subcategory(basar, maakhal).
subcategory(beheima, basar).
...
% Transitive closure
subcategory_of(X, Y) :- subcategory(X, Y).
subcategory_of(X, Z) :- subcategory(X, Y), subcategory_of(Y, Z).
Action Types¶
Madrega (Obligation Levels)¶
madrega_type(d_oraita). % Biblical (strongest)
madrega_type(d_rabanan). % Rabbinic
madrega_type(minhag). % Custom
madrega_type(chumra). % Stringency (weakest)
% Strength ordering
stronger(d_oraita, d_rabanan).
stronger(d_rabanan, minhag).
stronger(minhag, chumra).
Status Modalities¶
status(assur). % Prohibited
status(mutar). % Permitted
status(chiyuv). % Obligatory
status(reshut). % Optional
status(mitzvah). % Meritorious
status(sakanah). % Dangerous
Temperature Statuses¶
temp_status(tzonen). % Cold/room temperature
temp_status(cham). % Hot (yad soledet bo)
temp_status(roteiach). % Boiling
Kli (Vessel) Statuses¶
kli_status(kli_rishon). % Primary vessel (on fire)
kli_status(kli_sheni). % Secondary vessel (poured into)
kli_status(kli_shlishi). % Tertiary vessel
Context Types¶
context_type(ctx_normal). % Normal circumstances
context_type(ctx_hefsed). % Financial loss
context_type(ctx_shaat_hadchak). % Pressing need/emergency
disjointness.lp¶
Enforces mutual exclusivity between conflicting classifications.
Food Type Disjointness¶
A food cannot be classified as multiple top-level categories:
:- food_type(F, basar), food_type(F, chalav).
:- food_type(F, basar), food_type(F, parve).
:- food_type(F, chalav), food_type(F, parve).
Meat Subcategory Disjointness¶
A meat item can only come from one source:
:- food_type(F, beheima), food_type(F, chaya).
:- food_type(F, beheima), food_type(F, of).
:- food_type(F, beheima), food_type(F, dag).
:- food_type(F, chaya), food_type(F, of).
:- food_type(F, chaya), food_type(F, dag).
:- food_type(F, of), food_type(F, dag).
Normative Conflict Prevention¶
% Cannot be both forbidden and permitted
:- forbidden(W, A, F, C), permitted(W, A, F, C).
% One madrega per rule
:- madrega(R, M1), madrega(R, M2), M1 != M2.
constraints.lp¶
General integrity constraints for data quality.
Base Layer¶
substance.lp¶
Handles food type inheritance and mixture properties.
Food Type Inheritance¶
If a food is classified as a subcategory, it inherits parent categories:
% chicken is 'of' → also inherits 'basar' → also inherits 'maakhal'
food_type(F, Parent) :-
food_type(F, Child),
subcategory_of(Child, Parent).
Example:
food(chicken).
food_type(chicken, of). % Explicitly declared
% Automatically derived:
% food_type(chicken, basar). ← from subcategory(of, basar)
% food_type(chicken, maakhal). ← from subcategory(basar, maakhal)
Mixture Analysis¶
% Does mixture contain meat?
mixture_contains_basar(M) :-
mixture(M),
contains(M, F),
food_type(F, basar).
% Does mixture contain dairy?
mixture_contains_chalav(M) :-
mixture(M),
contains(M, F),
food_type(F, chalav).
% Is this a basar b'chalav mixture?
mixture_is_basar_bechalav(M) :-
mixture_contains_basar(M),
mixture_contains_chalav(M).
madrega.lp¶
Manages normative level hierarchy and rule priority.
Transitive Strength¶
stronger_transitive(M1, M2) :- stronger(M1, M2).
stronger_transitive(M1, M3) :- stronger(M1, M2), stronger_transitive(M2, M3).
This allows: d_oraita > d_rabanan > minhag > chumra
Rule Priority¶
rule_madrega_stronger(R1, R2) :-
rule(R1), rule(R2), R1 != R2,
madrega(R1, M1), madrega(R2, M2),
stronger_transitive(M1, M2).
Default Level¶
% Rules without explicit madrega default to d_rabanan
default_madrega(R, d_rabanan) :-
rule(R),
not madrega(R, d_oraita),
not madrega(R, d_rabanan),
not madrega(R, minhag),
not madrega(R, chumra).
context.lp¶
Handles situational leniency in halachic rulings.
Context Hierarchy¶
context(ctx_normal).
context(ctx_hefsed).
context(ctx_shaat_hadchak).
more_lenient_context(ctx_hefsed, ctx_normal).
more_lenient_context(ctx_shaat_hadchak, ctx_normal).
more_lenient_context(ctx_shaat_hadchak, ctx_hefsed).
Permission Inheritance¶
What's permitted in a stricter context is also permitted in a more lenient one:
permitted(W, A, F, C_lenient) :-
permitted(W, A, F, C_strict),
more_lenient_transitive(C_lenient, C_strict).
Example: If eating X is permitted under ctx_normal, it's automatically permitted under ctx_hefsed and ctx_shaat_hadchak.
temporal.lp¶
Time-based reasoning for absorption and taste transfer.
Ben Yomo (24-hour rule)¶
% Vessel used within 24 hours
ben_yomo(V) :-
vessel(V),
hours_since_use(V, H),
H < 24.
% Vessel not used within 24 hours
eino_ben_yomo(V) :-
vessel(V),
hours_since_use(V, H),
H >= 24.
Kavush (Soaking Rule)¶
% 24-hour soaking transfers taste like cooking
kavush_complete(F, V) :-
soaking(F, V),
hours_soaking(F, V, H),
H >= 24.
Noten Taam Lifgam¶
% Taste is worsened after 24 hours (unless sharp food used)
pagum(V) :-
eino_ben_yomo(V),
not used_with_davar_charif(V).
not_pagum(V) :-
vessel(V),
ben_yomo(V).
not_pagum(V) :-
eino_ben_yomo(V),
used_with_davar_charif(V).
Yad Soledet Bo¶
yad_soledet_threshold(45). % Celsius
is_yad_soledet(F) :-
food(F),
temperature_celsius(F, T),
yad_soledet_threshold(Threshold),
T >= Threshold.
status.lp¶
Normative status classifications and derivations.
shiur.lp¶
Measurement definitions and bitul (nullification) calculations.
issur_types.lp¶
Prohibition type classifications (eating, benefit, cooking, mixture, vessel).
Extensions Layer¶
User-defined extensions go in mistaber/ontology/extensions/.
Extension Protocol¶
- Proposal: Document concept with Hebrew name, source citation, sort membership
- Schema Definition: Write the ASP code with proper metadata
- Consistency Check: Run clingo to verify no conflicts
- Human Review: Verify halachic and technical accuracy
- Version Tracking: Include date, author, changelog
Example Extension¶
% Extension: kitniyot
% Source: Shulchan Arukh OC 453:1
% Added: 2026-01-20
food_category(kitniyot).
kitniyot_item(rice).
kitniyot_item(corn).
forbidden(W, achiila, F, ctx_pesach) :-
active_in_world(r_kitniyot, W),
food(F),
kitniyot_item(FoodName).
rule(r_kitniyot).
scope(r_kitniyot, ashkenaz).
makor(r_kitniyot, sa("oc:453:1")).
madrega(r_kitniyot, minhag).
Integration¶
Extensions are automatically loaded after schema and base ontology. They can reference any existing predicate.
Loading Order¶
1. mistaber/ontology/schema/sorts.lp
2. mistaber/ontology/schema/constraints.lp
3. mistaber/ontology/schema/disjointness.lp
4. mistaber/ontology/base/*.lp
5. mistaber/ontology/extensions/*.lp (optional)
6. User-compiled HLL code
Testing the Ontology¶
Satisfiability Test¶
clingo mistaber/ontology/schema/*.lp mistaber/ontology/base/*.lp --warn=none 0
# Expected: SATISFIABLE
With User Facts¶
clingo mistaber/ontology/schema/*.lp mistaber/ontology/base/*.lp - <<EOF
food(chicken).
food_type(chicken, of).
food(milk).
food_type(milk, chalav).
mixture(m1).
contains(m1, chicken).
contains(m1, milk).
#show mixture_is_basar_bechalav/1.
EOF
# Expected: mixture_is_basar_bechalav(m1)
Python API¶
import clingo
ctl = clingo.Control(["--warn=none"])
ctl.load("mistaber/ontology/schema/sorts.lp")
ctl.load("mistaber/ontology/schema/disjointness.lp")
ctl.load("mistaber/ontology/base/substance.lp")
ctl.add("user", [], """
food(beef).
food_type(beef, beheima).
food(milk).
food_type(milk, chalav).
mixture(m1).
contains(m1, beef).
contains(m1, milk).
""")
ctl.ground([("base", []), ("user", [])])
with ctl.solve(yield_=True) as handle:
for model in handle:
atoms = [str(a) for a in model.symbols(shown=True)]
if "mixture_is_basar_bechalav(m1)" in atoms:
print("Detected basar b'chalav!")
Key Design Principles¶
1. Hierarchical Inheritance¶
Categories form inheritance trees. Classifying at a specific level automatically includes parent classifications.
2. Disjointness Enforcement¶
The schema prevents logically impossible states (e.g., food that is both meat and dairy).
3. Context Sensitivity¶
Rulings can vary by context, with automatic permission inheritance to more lenient contexts.
4. Madrega-Based Priority¶
When rules conflict, the stronger normative level takes precedence.
5. Temporal Awareness¶
The 24-hour rule and other time-based concepts are built into the base layer.