HLL Encoding¶
The HLL encoding phase transforms the approved corpus into formal Halachic Logic Language (HLL) rules. This is where source texts become executable logic that the Mistaber reasoning engine can process. The hll-encode skill guides this transformation and produces artifacts for human review at Checkpoint 2.
Purpose¶
The hll-encode skill accomplishes:
- Statement Transformation: Convert atomic statements to formal rules
- World Scoping: Assign rules to appropriate worlds (base, mechaber, rema)
- Machloket Encoding: Represent disputes with opposing rules and override mechanism
- Makor Attachment: Ensure every rule has complete source attribution
- Pre-compile Validation: Catch errors before full compilation
Prerequisites¶
Before invoking this skill:
- Corpus-prep checkpoint MUST be approved
- Session state shows
corpus-prep.status: approved - Corpus artifacts are available in
.mistaber-artifacts/
Invoking the Skill¶
After corpus approval:
The skill automatically:
- Loads approved corpus and ontology context
- Transforms statements to rules
- Generates world-scoped rules
- Runs pre-compile validation
- Requests checkpoint approval
Phase A: Encoding Context Initialization¶
Step 1: Load Approved Corpus¶
The skill reads the approved corpus files:
# Load sources YAML
corpus = yaml.safe_load(
open(".mistaber-artifacts/corpus-sources-YD-87-1.yaml")
)
# Load resolved questions
questions = yaml.safe_load(
open(".mistaber-artifacts/corpus-questions-YD-87-1.yaml")
)
It extracts:
- Atomic statements with types
- Commentary classifications
- Machloket entries
- Derivation chains
- Human-resolved questions
Step 2: Load Ontology Context¶
The skill reads the current ontology state:
# Read predicate registry
predicates = read_file("mistaber/ontology/schema/sorts.lp")
# Read existing worlds
worlds = read_file("mistaber/ontology/worlds/kripke_rules.lp")
# Read existing corpus rules for context
existing = glob("mistaber/ontology/corpus/yd_87/*.lp")
This ensures:
- Predicates are used consistently
- World names match existing definitions
- No duplicate rule IDs
Step 3: Initialize Rule ID Generator¶
Rule IDs follow a topic-based pattern (NOT siman-seif based):
Common Topic Prefixes:
| Prefix | Topic | Example |
|---|---|---|
r_bb_* |
basar bechalav (meat and milk) | r_bb_beheima_achiila |
r_bb_dag_* |
fish-related rules within basar bechalav | r_bb_dag_no_bb |
r_rema_* |
Rema-specific rules | r_rema_dag_chalav_mutar |
r_yo_* |
Yalkut Yosef rules | r_yo_dag_sakana |
Rule ID Examples:
| Rule ID | Meaning |
|---|---|
r_bb_beheima_achiila |
Basar bechalav prohibition for eating beheima |
r_bb_bishul_doraita |
Basar bechalav cooking prohibition (d'oraita) |
r_bb_dag_no_bb |
Fish has no basar bechalav issur |
r_rema_dag_chalav_mutar |
Rema's permission for fish with dairy |
Step 4: Load Encoding Templates¶
The skill references encoding patterns from the plugin's reference files for consistent rule generation.
Phase B: Statement-to-Rule Transformation¶
For each atomic statement from the corpus, the skill performs a structured transformation.
Step 1: Statement Classification¶
Map statement type to rule category:
| Statement Type | Rule Category | Primary Predicate |
|---|---|---|
ISSUR |
Prohibition | asserts(W, issur(action, M, level)) |
ISSUR_SAKANA |
Health danger | asserts(W, sakana(M)) |
HETER |
Permission | asserts(W, heter(action, M)) |
CHIYUV |
Obligation | asserts(W, chiyuv(action, M, level)) |
DEFINITION |
Category | is_X(entity) predicate |
CONDITION |
Prerequisite | Part of rule body |
EXCEPTION |
Override | override/3 or NAF |
Step 2: Predicate Selection¶
The skill matches statements to predicates in the ontology:
Example mapping:
# Statement: "Meat and milk is forbidden to eat"
predicate: issur
arity: 3
arguments:
- action: achiila
- mixture: M (variable)
- level: d_oraita
The skill validates predicate existence:
Refer to Predicate Registry for all available predicates.
Step 3: Argument Mapping¶
Map statement entities to ASP variables/constants:
| Entity Type | Mapping | Example |
|---|---|---|
| Generic mixture | Variable M |
mixture(M) |
| Specific food | Constant | food(salmon) |
| Action type | Constant | achiila, bishul, hanaah |
| Level | Constant | d_oraita, d_rabanan |
Variable Naming Conventions:
| Variable | Represents |
|---|---|
M |
Mixture |
F |
Food |
W |
World |
V |
Vessel |
A |
Action |
L |
Level (madrega) |
Step 4: Condition Extraction¶
Parse conditional language into rule body:
| Natural Language | ASP Body |
|---|---|
| "If X contains Y" | contains(X, Y) |
| "When cooked together" | mixture(M), cooked(M) |
| "Unless nullified" | not batel(M) |
| "In case of X" | context(X) |
| "Only if taste transfers" | noten_taam(M) |
Step 5: Madrega Assignment¶
Determine the normative level based on:
- Derivation chain terminus - Torah source = d_oraita
- Explicit statement - "d'rabanan" in source text
- Commentary classification - How commentators describe it
% D'oraita - has Torah source
madrega(r_bb_beheima_achiila, d_oraita).
% D'rabanan - rabbinic extension
madrega(r_bb_of_achiila, d_rabanan).
% Minhag - custom
madrega(r_waiting_six_hours, minhag).
% Chumra - stringency
madrega(r_separate_ovens, chumra).
Phase C: World-Scoped Rule Generation¶
Scope Decision Tree¶
The skill uses this decision tree to determine world scope:
flowchart TD
A[Statement] --> B{Universal ruling?<br/>All poskim agree?}
B -->|Yes| C[base world]
B -->|No| D{Mechaber/Rema split?}
D -->|Yes| E[mechaber + rema worlds]
D -->|No| F{Commentary dispute?}
F -->|Yes| G[interpretation layer<br/>shach/taz worlds]
F -->|No| H{Modern authority ruling?}
H -->|Yes| I[tier 3 world<br/>sefardi_yo/ashk_mb]
H -->|No| C
Base World Rules¶
For universally agreed rulings, place in the base world:
% mistaber/ontology/corpus/yd_87/base.lp
% Shared definitions for YD 87 - Basar Bechalav
#include "../../schema/sorts.lp".
% === FOOD TYPE DEFINITIONS ===
basar_type(beheima).
basar_type(of).
basar_type(dag).
% === MIXTURE PREDICATES ===
is_beheima_chalav_mixture(M) :-
mixture(M),
mixture_has_basar(M, beheima),
mixture_has_chalav(M).
is_dag_chalav_mixture(M) :-
mixture(M),
mixture_has_basar(M, dag),
mixture_has_chalav(M).
% === UNIVERSAL RULES (base world) ===
% All authorities agree: beheima + chalav is forbidden d'oraita
rule(r_bb_beheima_achiila).
makor(r_bb_beheima_achiila, sa("yd:87:1")).
makor(r_bb_beheima_achiila, torah("shemot:23:19")).
madrega(r_bb_beheima_achiila, d_oraita).
scope(r_bb_beheima_achiila, base).
asserts(base, issur(achiila, M, d_oraita)) :-
is_beheima_chalav_mixture(M).
Mechaber World Rules¶
For Sefardi-specific rulings:
% mistaber/ontology/worlds/mechaber.lp
#include "../corpus/yd_87/base.lp".
% === MECHABER-SPECIFIC: DAG + CHALAV SAKANA ===
% Mechaber holds: Fish + dairy has SAKANA (health danger)
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).
% Assert sakana for fish-dairy mixture
asserts(mechaber, sakana(M)) :-
is_dag_chalav_mixture(M).
% Sakana creates an issur
asserts(mechaber, issur(achiila, M, sakana)) :-
is_dag_chalav_mixture(M).
Rema World Rules¶
For Ashkenazi-specific rulings with overrides:
% mistaber/ontology/worlds/rema.lp
#include "../corpus/yd_87/base.lp".
% === REMA-SPECIFIC: DAG + CHALAV MUTAR ===
% Rema DISAGREES with Mechaber - no sakana for fish + dairy
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 Mechaber's sakana ruling
% IMPORTANT: Third argument is the NEW VALUE (descriptive), not 'invalid'
override(rema, sakana(M), no_sakana) :-
is_dag_chalav_mixture(M).
% Explicitly assert permission
asserts(rema, heter(achiila, M)) :-
is_dag_chalav_mixture(M).
% Assert the positive: no sakana
asserts(rema, no_sakana(M)) :-
is_dag_chalav_mixture(M).
Tier 3 World Rules¶
For modern authorities that follow earlier positions:
% mistaber/ontology/worlds/sefardi_yo.lp
#include "../corpus/yd_87/base.lp".
% === SEFARDI_YO (Yalkut Yosef) ===
% Follows Mechaber - maintains dag sakana
rule(r_yo_dag_sakana).
makor(r_yo_dag_sakana, yalkut_yosef("yd:87:3")).
scope(r_yo_dag_sakana, sefardi_yo).
% Inherits mechaber's sakana via accessible/2
% No need to redefine - accessible(sefardi_yo, mechaber)
Phase D: Machloket Encoding¶
Step 1: Structure the Dispute¶
From the corpus machloket entry:
machloket:
topic: dag_bechalav
positions:
- authority: mechaber
ruling: sakana
- authority: rema
ruling: mutar
practical_difference: "Fish with dairy dishes"
Step 2: Generate Opposing Rules¶
Each position gets rules in its world (already generated in Phase C).
Step 3: Generate Machloket Marker¶
Create a detection predicate:
% Machloket marker for detection and comparison queries
machloket(dag_chalav, mechaber, rema, M) :-
is_dag_chalav_mixture(M).
This allows queries like:
Step 4: Documentation Comments¶
Add explanatory comment blocks:
% ============================================================================
% MACHLOKET: Fish and Dairy (Dag Bechalav)
% ============================================================================
% Mechaber: Forbidden due to sakana (health danger)
% Source: Beit Yosef citing medical sources
% Practical: Sefardim avoid fish cooked/served with dairy
%
% Rema: Permitted (Ashkenazi practice)
% Source: Rema's silence + explicit Taz/Shach clarification
% Practical: Ashkenazim permit lox with cream cheese, fish in cream sauce
%
% Cross-ref: YD 116 for general sakana rules
% ============================================================================
Phase E: Context and Exception Handling¶
Context-Sensitive Rules¶
Encode lechatchila/bedieved distinctions:
% Lechatchila (ideally): Do not mix
asserts(W, issur(achiila, M, L)) :-
world(W),
is_basar_chalav_mixture(M),
context(lechatchila).
% Bedieved (after the fact): May be permitted if unintentional
asserts(W, heter(achiila, M)) :-
world(W),
is_basar_chalav_mixture(M),
context(bedieved),
batel_b_shishim(M),
not intentional_mixture(M).
Exception Encoding with NAF¶
Use negation-as-failure for "unless" clauses:
% "Forbidden UNLESS nullified in 60:1"
asserts(W, issur(achiila, M, L)) :-
world(W),
is_basar_chalav_mixture(M),
not batel_b_shishim(M).
% Nullification rule
batel_b_shishim(M) :-
mixture(M),
ratio(M, heter, issur, R),
R >= 60.
Safek Handling¶
Encode doubt resolution based on madrega:
% Safek d'oraita l'chumra (default)
safek_resolution(W, Query, chumra) :-
world(W),
query_madrega(Query, d_oraita),
safek_policy(W, d_oraita, l_chumra).
% Safek d'rabanan l'kula
safek_resolution(W, Query, kula) :-
world(W),
query_madrega(Query, d_rabanan),
safek_policy(W, d_rabanan, l_kula).
Phase F: Makor Chain Attachment¶
Primary Makor¶
Every normative rule MUST have at least one makor:
Chain Makor¶
For d'oraita rules, add full derivation chain:
% Full chain for beheima achiila
makor(r_bb_beheima_achiila, sa("yd:87:1")).
makor(r_bb_beheima_achiila, tur("yd:87")).
makor(r_bb_beheima_achiila, rambam("maachalot:9:1")).
makor(r_bb_beheima_achiila, gemara("chullin:104b")).
makor(r_bb_beheima_achiila, mishnah("chullin:8:1")).
makor(r_bb_beheima_achiila, torah("shemot:23:19")).
Source Type Reference¶
| Source Type | Format | Example |
|---|---|---|
sa |
Shulchan Aruch | sa("yd:87:1") |
rema |
Rema gloss | rema("yd:87:3") |
tur |
Arba'ah Turim | tur("yd:87") |
rambam |
Mishneh Torah | rambam("maachalot:9:1") |
beit_yosef |
Beit Yosef | beit_yosef("yd:87") |
shach |
Siftei Kohen | shach("yd:87:5") |
taz |
Turei Zahav | taz("yd:87:3") |
gemara |
Talmud Bavli | gemara("chullin:104b") |
mishnah |
Mishnah | mishnah("chullin:8:1") |
torah |
Chumash | torah("shemot:23:19") |
yalkut_yosef |
Yalkut Yosef | yalkut_yosef("yd:87:3") |
Completeness Verification¶
Every rule must have:
- [ ] At least one
makor/2fact - [ ] For normative rules:
madrega/2fact - [ ] For scoped rules:
scope/2fact
Phase G: Static Validation (Pre-Compile)¶
Step 1: Syntax Validation¶
Check all rules for:
- Correct ASP syntax (
.terminator) - Balanced parentheses
- Valid variable names (uppercase start)
- Valid constant names (lowercase start)
Step 2: Predicate Validation¶
For each used predicate:
for pred, arity in used_predicates:
assert predicate_in_registry(pred, arity), \
f"Unknown predicate: {pred}/{arity}"
Step 3: Directive Validation¶
Verify HLL directives:
| Directive | Validation |
|---|---|
@world |
Must be valid world name |
@makor |
Must have valid source format |
@madrega |
Must use valid level |
@rule |
Must have unique ID |
Step 4: World Consistency¶
Check world references:
valid_worlds = ["base", "mechaber", "rema", "shach", "taz",
"sefardi_yo", "ashk_mb", "ashk_ah", "gra"]
for world in referenced_worlds:
assert world in valid_worlds, f"Unknown world: {world}"
Step 5: Cross-Reference Validation¶
Verify referenced predicates are defined:
Phase H: Output Generation¶
Output 1: HLL Rules Files¶
File Organization (CRITICAL):
- Shared definitions:
mistaber/ontology/corpus/yd_{siman}/base.lp - World-specific rules:
mistaber/ontology/worlds/{world}.lp
World files use #include to incorporate shared definitions:
Example File Structure After Encoding:
mistaber/ontology/
├── corpus/
│ └── yd_87/
│ ├── base.lp # Shared definitions (new/updated)
│ └── manifest.yaml # Siman metadata
├── worlds/
│ ├── mechaber.lp # Mechaber rules (updated)
│ ├── rema.lp # Rema rules (updated)
│ └── ...
└── schema/
└── sorts.lp # Predicate definitions
Output 2: Encoding Report¶
encoding-report-YD-{siman}-{seif}.md
# Encoding Report: YD 87:1
## Summary
- **Reference:** YD 87:1
- **Encoded at:** 2026-01-25T14:00:00Z
- **Rules Created:** 8
- **Worlds Affected:** base, mechaber, rema
## Rules Generated
### Base World (2 rules)
1. `r_bb_beheima_achiila` - Beheima eating prohibition
2. `r_bb_beheima_bishul` - Beheima cooking prohibition
### Mechaber World (3 rules)
3. `r_bb_dag_sakana` - Fish-dairy sakana
4. `r_bb_dag_issur` - Fish-dairy prohibition
5. `r_bb_hanaah` - Benefit prohibition
### Rema World (3 rules)
6. `r_rema_dag_chalav_mutar` - Fish-dairy permission
7. `r_rema_no_sakana` - No sakana assertion
8. `r_rema_dag_heter` - Explicit heter
## Statement-Rule Mapping
[Traceability table]
## Machloket Encoding
[Dispute details]
## Pre-Compile Results
[Validation output]
Output 3: Statement-Rule Mapping¶
encoding-mapping-YD-{siman}-{seif}.yaml
reference: "YD:87:3"
encoded_at: "2026-01-25T14:00:00Z"
mappings:
- statement_id: s1
rule_ids:
- r_bb_dag_no_bb
predicate: "definition"
notes: "Definition - no BB prohibition for fish"
- statement_id: s2
rule_ids:
- r_bb_dag_bishul_mutar
- r_bb_dag_achiila_mutar
predicate: "heter"
notes: "Permission to cook and eat"
- statement_id: s3
rule_ids:
- r_bb_dag_sakana
predicate: "sakana/issur"
world: mechaber
machloket: true
notes: "Mechaber's sakana position - disputed by Rema"
- statement_id: s3_rema
rule_ids:
- r_rema_dag_chalav_mutar
predicate: "heter"
world: rema
machloket: true
notes: "Rema's opposing position"
Output 4: Pre-Compile Results¶
encoding-validation-YD-{siman}-{seif}.yaml
reference: "YD:87:3"
validated_at: "2026-01-25T14:30:00Z"
syntax_check:
status: passed
issues: []
predicate_check:
status: passed
predicates_used: 12
all_registered: true
list:
- issur/3
- heter/2
- sakana/1
- is_dag_chalav_mixture/1
# ...
directive_check:
status: passed
rules_with_makor: 8
rules_with_madrega: 8
missing_makor: []
world_check:
status: passed
worlds_referenced: [base, mechaber, rema]
all_exist: true
summary:
total_rules: 8
base_rules: 2
world_specific: 6
machloket_markers: 1
ready_for_compilation: true
Checkpoint Criteria¶
Before requesting human approval, verify:
- [ ] All atomic statements have corresponding rules
- [ ] Predicates correctly chosen and validated against registry
- [ ] World scoping accurate (base vs. specific)
- [ ] Machloket properly encoded with both positions
- [ ] Makor chain complete for all rules
- [ ] Madrega levels correct (d_oraita/d_rabanan/etc.)
- [ ] Pre-compile validation passes
- [ ] All four outputs generated
Session State Update¶
After completing encoding:
current_phase: hll-encode
checkpoints:
hll-encode:
status: pending_review
artifacts:
# Shared definitions
- path: mistaber/ontology/corpus/yd_87/base.lp
type: shared_definitions
new_content: true
# World-specific rules
- path: mistaber/ontology/worlds/mechaber.lp
rules_added: 3
world: mechaber
- path: mistaber/ontology/worlds/rema.lp
rules_added: 3
world: rema
# Reports
- encoding-report-YD-87-1.md
- encoding-mapping-YD-87-1.yaml
- encoding-validation-YD-87-1.yaml
rules_count: 8
worlds_affected: [base, mechaber, rema]
Common Patterns¶
Pattern 1: Simple Prohibition¶
rule(r_simple_issur).
makor(r_simple_issur, sa("yd:XX:Y")).
madrega(r_simple_issur, d_oraita).
scope(r_simple_issur, base).
asserts(base, issur(achiila, M, d_oraita)) :-
matching_condition(M).
Pattern 2: Machloket with Override¶
% Position A (in mechaber.lp)
rule(r_position_a).
asserts(mechaber, ruling_a(M)) :- condition(M).
% Position B (in rema.lp)
rule(r_position_b).
override(rema, ruling_a(M), ruling_b) :- condition(M).
asserts(rema, ruling_b(M)) :- condition(M).
% Marker
machloket(topic, mechaber, rema, M) :- condition(M).
Pattern 3: Conditional Ruling¶
rule(r_conditional).
% Applies only when context is bedieved
asserts(W, heter(achiila, M)) :-
world(W),
condition(M),
context(bedieved).
Pattern 4: Definition with Classification¶
% Food is considered basar
is_basar(F) :- food(F), food_type(F, beheima).
is_basar(F) :- food(F), food_type(F, chaya).
is_basar(F) :- food(F), food_type(F, of).
Troubleshooting¶
"Unknown predicate X/N"¶
- Check Predicate Registry
- If predicate should exist, check spelling
- If new predicate needed, document and add to
sorts.lp
"Rule ID already exists"¶
- Use topic-based naming:
r_{topic}_{specific} - Avoid sequential numbers:
r_1,r_2 - Be specific:
r_bb_beheima_achiilanotr_bb_1
"World inheritance not working"¶
- Verify
#includestatements - Check
accessible/2rules inkripke_rules.lp - Ensure base rules use
asserts(base, ...)notasserts(mechaber, ...)
"Override not taking effect"¶
- Third argument must be descriptive value, not 'invalid'
- Ensure condition in override matches original rule
- Check that override world is accessible from base
Best Practices¶
- Use topic-based rule IDs -
r_bb_achiilanotr_87_1_1 - Document machloket thoroughly - Include sources for both positions
- Keep shared definitions in base.lp - World files only add specific rules
- Test override mechanism - Ensure both positions are derivable
- Validate before checkpoint - Catch errors early
Next Phase¶
After Checkpoint 2 approval, proceed to Validation and Testing.