HLL Encoding Skill¶
The hll-encode skill transforms approved corpus preparation artifacts into HLL (Halachic Logic Language) rules with proper world scoping, makor attribution, madrega levels, and ASP-compatible syntax.
Overview¶
| Attribute | Value |
|---|---|
| Skill Name | hll-encode |
| Phase | 2 of 5 |
| Checkpoint | 2: Rule Review |
| Prerequisites | Checkpoint 1 (corpus-prep) approved |
| Outputs | base.lp, world-specific .lp files, encoding-report.md, encoding-mapping.yaml |
| Trigger Phrases | "encode rules", "write HLL", "create ASP rules", "encode seif", "translate to HLL", "encode machloket" |
Prerequisites¶
Before this skill can execute:
- Corpus-prep checkpoint MUST be approved
- Corpus artifacts must exist:
corpus-sources-YD-{siman}-{seif}.yamlcorpus-questions-YD-{siman}-{seif}.yaml(with resolved answers)- Session state shows
corpus-prep.status: approved
Phase A: Encoding Context Initialization¶
Step 1: Load Approved Corpus¶
The skill loads the approved corpus files:
# From corpus-sources-YD-87-3.yaml
statements:
- id: s1
type: DEFINITION
text_en: "Fish and locusts have no basar bechalav prohibition"
world_context: base
- id: s2
type: HETER
text_en: "Permitted to cook them with milk"
world_context: base
- id: s3
type: ISSUR_SAKANA
text_en: "But forbidden to eat together due to danger"
world_context: mechaber # Disputed
machloket:
- id: m1
topic: dag_bechalav
position_a:
authority: mechaber
ruling: sakana
position_b:
authority: rema
ruling: mutar
Step 2: Load Ontology Context¶
The skill reads 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 this siman
existing = glob("mistaber/ontology/corpus/yd_{siman}/*.lp")
Step 3: Initialize Rule ID Generator¶
Rule IDs follow a topic-based pattern (NOT siman-seif):
Topic Prefixes:
| Prefix | Topic |
|---|---|
r_bb_* |
Basar bechalav (meat and milk) |
r_bb_dag_* |
Fish-related rules within basar bechalav |
r_rema_* |
Rema-specific (authority prefix) |
r_yo_* |
Yalkut Yosef rules |
r_mb_* |
Mishnah Berurah rules |
Examples:
| Rule ID | Meaning |
|---|---|
r_bb_beheima_achiila |
Basar bechalav beheima eating |
r_bb_dag_no_bb |
Fish has no BB issur |
r_rema_dag_chalav_mutar |
Rema's fish-dairy permission |
r_yo_dag_sakana |
Yalkut Yosef's fish sakana |
Phase B: Statement-to-Rule Transformation¶
Step 1: Statement Classification¶
Each statement type maps to a rule category:
| Statement Type | Rule Category | Primary Predicate |
|---|---|---|
| ISSUR | Prohibition | issur(action, M, level) |
| ISSUR_SAKANA | Health danger | sakana(M) |
| HETER | Permission | heter(action, M) |
| CHIYUV | Obligation | chiyuv(action, M, level) |
| DEFINITION | Category | is_X(entity) |
| CONDITION | Prerequisite | Part of rule body |
| EXCEPTION | Override | override/3 or NAF |
Step 2: Predicate Selection¶
Statements are mapped to predicates in the ontology:
# Statement: "Fish + dairy is forbidden to eat due to sakana"
# Maps to:
predicate: sakana
arity: 1
arguments:
- mixture: M (variable)
secondary_predicate: issur
secondary_arguments:
- action: achiila
- mixture: M
- level: sakana
The skill validates predicates exist:
Step 3: Argument Mapping¶
Statement entities map 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, sakana |
Step 4: Condition Extraction¶
Conditional language parses to 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) |
Step 5: Madrega Assignment¶
Normative level is determined from:
- Derivation chain terminus (Torah = d_oraita)
- Explicit statement in SA ("d'rabanan")
- Commentary classification
% D'oraita - has Torah source
madrega(r_bb_achiila, d_oraita).
% D'rabanan - rabbinic extension
madrega(r_extended_rule, d_rabanan).
% Sakana - health danger (special level)
madrega(r_bb_dag_sakana, sakana).
% Minhag - custom
madrega(r_minhag_rule, minhag).
% Chumra - stringency
madrega(r_strict_rule, chumra).
Phase C: World-Scoped Rule Generation¶
Scope Decision Tree¶
graph TD
A[Statement] --> B{Universal?}
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]
F -->|No| H{Modern Authority?}
H -->|Yes| I[Tier 3 World]
H -->|No| C
Base World Rules¶
For universally agreed rulings, rules go in corpus/yd_{siman}/base.lp:
% mistaber/ontology/corpus/yd_87/base.lp
% Yoreh Deah Siman 87: Basar Bechalav - Shared Definitions
%
% This file contains definitions and rules that ALL authorities agree upon.
% World-specific rules go in worlds/*.lp files.
#include "../../schema/sorts.lp".
% === FOOD TYPE DEFINITIONS ===
basar_type(beheima).
basar_type(of).
basar_type(dag).
basar_type(chaya).
% === MIXTURE PREDICATES ===
is_beheima_chalav_mixture(M) :-
mixture_has_basar(M, beheima),
mixture_has_chalav(M).
is_dag_chalav_mixture(M) :-
mixture_has_basar(M, dag),
mixture_has_chalav(M).
% === SEIF 1: UNIVERSAL RULES ===
% All 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).
% === SEIF 3: FISH HAS NO BB ISSUR (UNIVERSAL) ===
% All agree: Fish has no basar bechalav prohibition
rule(r_bb_dag_no_bb).
makor(r_bb_dag_no_bb, sa("yd:87:3")).
scope(r_bb_dag_no_bb, base).
asserts(base, no_bb_issur(M)) :-
is_dag_chalav_mixture(M).
Mechaber World Rules¶
For Sefardi-specific rulings, rules go in worlds/mechaber.lp:
% mistaber/ontology/worlds/mechaber.lp
% Mechaber (Sefardi) World-Specific Rules
#include "../corpus/yd_87/base.lp".
% === YD 87:3 - DAG + CHALAV SAKANA (MECHABER ONLY) ===
rule(r_bb_dag_sakana).
makor(r_bb_dag_sakana, sa("yd:87:3")).
makor(r_bb_dag_sakana, beit_yosef("yd:87")).
madrega(r_bb_dag_sakana, sakana).
scope(r_bb_dag_sakana, mechaber).
% Fish + dairy triggers sakana
asserts(mechaber, sakana(M)) :-
is_dag_chalav_mixture(M).
% Sakana implies issur achiila
asserts(mechaber, issur(achiila, M, sakana)) :-
is_dag_chalav_mixture(M),
holds(sakana(M), mechaber).
Rema World Rules¶
For Ashkenazi-specific rulings with overrides, rules go in worlds/rema.lp:
% mistaber/ontology/worlds/rema.lp
% Rema (Ashkenazi) World-Specific Rules
#include "../corpus/yd_87/base.lp".
% === YD 87:3 - DAG + CHALAV MUTAR (REMA) ===
% Rema disagrees with Mechaber on 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
% CRITICAL: Third argument is DESCRIPTIVE VALUE, 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 no sakana in this world
asserts(rema, no_sakana(M)) :-
is_dag_chalav_mixture(M).
Tier 3 World Rules¶
For modern authorities (e.g., in worlds/sefardi_yo.lp):
% mistaber/ontology/worlds/sefardi_yo.lp
% Sefardi (Yalkut Yosef) World-Specific Rules
#include "../corpus/yd_87/base.lp".
% === SEFARDI_YO (Yalkut Yosef) ===
% Inherits from mechaber, follows 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 - no override needed
% World inheritance handles this automatically
Phase D: Machloket Encoding¶
Step 1: Structure the Dispute¶
From the corpus machloket data:
machloket:
topic: dag_bechalav
positions:
- authority: mechaber
ruling: sakana
world: mechaber
- authority: rema
ruling: mutar
world: rema
practical_difference: "Fish with dairy dishes (lox + cream cheese)"
Step 2: Generate Opposing Rules¶
(Already generated in Phase C world-specific rules)
Step 3: Generate Machloket Marker¶
% Machloket marker for automated detection
machloket(dag_chalav, mechaber, rema, M) :-
is_dag_chalav_mixture(M).
Step 4: Documentation Comments¶
% ============================================================================
% MACHLOKET: Fish and Dairy (Dag Bechalav)
% ============================================================================
% Mechaber: Forbidden due to sakana (health danger)
% Source: Beit Yosef citing medical sources
% Worlds: mechaber, sefardi_yo
%
% Rema: Permitted (Ashkenazi practice)
% Source: Rema's silence + explicit Taz/Shach clarification
% Worlds: rema, ashk_mb, ashk_ah
%
% Practical: Lox with cream cheese, fish in cream sauce, gefillte fish + butter
% ============================================================================
Phase E: Context & Exception Handling¶
Lechatchila/Bedieved Distinctions¶
% Lechatchila: Ideally, Sefardim avoid fish + dairy
asserts(mechaber, issur(achiila, M, sakana)) :-
is_dag_chalav_mixture(M),
context(lechatchila).
% Bedieved: If already mixed, some poskim are lenient
% (Encode if commentary supports)
asserts(mechaber, heter(achiila, M)) :-
is_dag_chalav_mixture(M),
context(bedieved),
hefsed_merubeh. % Significant financial loss
Exception Encoding with NAF¶
% "Forbidden UNLESS nullified in 60:1"
asserts(W, issur(achiila, M, Level)) :-
is_basar_chalav_mixture(M),
not batel_b_shishim(M).
% "Permitted IF already mixed AND not intentional"
asserts(W, heter(achiila, M)) :-
is_basar_chalav_mixture(M),
batel_b_shishim(M),
not intentional_mixture(M).
Override Semantics¶
CRITICAL: Always use descriptive values for override/3
% CORRECT: Third argument describes the new state
override(rema, sakana(M), no_sakana) :- ...
override(gra, strict_ruling(X), lenient_ruling) :- ...
% WRONG: Never use 'invalid' as third argument
% override(rema, sakana(M), invalid) :- ... % DO NOT DO THIS
Phase F: Makor Chain Attachment¶
Primary Makor¶
Every normative rule MUST have at least one makor:
Full Chain for D'oraita Rules¶
% 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")).
Completeness Verification¶
Every rule must have:
- [ ] At least one
makor/2fact - [ ] For normative rules:
madrega/2fact - [ ] For scoped rules:
scope/2fact
Phase G: Pre-Compile Validation¶
Syntax Validation¶
- Correct ASP syntax (
.terminator) - Balanced parentheses
- Valid variable names (uppercase start)
- Valid constant names (lowercase start)
Predicate Validation¶
for pred, arity in used_predicates:
assert predicate_in_registry(pred, arity), \
f"Unknown predicate: {pred}/{arity}"
World Validation¶
VALID_WORLDS = {"base", "mechaber", "rema", "gra", "sefardi_yo", "ashk_mb", "ashk_ah"}
for world in referenced_worlds:
assert world in VALID_WORLDS, f"Unknown world: {world}"
Phase H: Output Generation¶
Output 1: Shared Definitions File¶
mistaber/ontology/corpus/yd_{siman}/base.lp
Contains: - Sort definitions shared across worlds - Mixture predicate definitions - Universal rules (no machloket)
Output 2: World-Specific Files¶
mistaber/ontology/worlds/{world}.lp
Contains:
- #include of shared definitions
- World-specific rules
- Override declarations
- Machloket markers
Output 3: Encoding Report¶
encoding-report-YD-{siman}-{seif}.md
Uses template from templates/encoding-report.md:
- Statement-to-rule mapping table
- World distribution summary
- Rule details with encoding
- Machloket documentation
- Pre-compile validation results
Output 4: Encoding 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"
Checkpoint Criteria¶
Before requesting human approval:
- [ ] All atomic statements have corresponding rules
- [ ] Predicates correctly chosen and validated
- [ ] World scoping accurate (base vs. specific)
- [ ] Machloket properly encoded with both positions
- [ ] Makor chain complete for all rules
- [ ] Madrega levels correct
- [ ] Pre-compile validation passes
- [ ] All outputs generated
Session State Update¶
After completing encoding:
current_phase: hll-encode
checkpoints:
hll-encode:
status: pending_review
artifacts:
- path: mistaber/ontology/corpus/yd_87/base.lp
type: shared_definitions
- path: mistaber/ontology/worlds/mechaber.lp
rules_count: 4
world: mechaber
- path: mistaber/ontology/worlds/rema.lp
rules_count: 4
world: rema
- encoding-report-YD-87-3.md
- encoding-mapping-YD-87-3.yaml
Common Issues¶
Missing Makor Attribution¶
The encoding-guard hook will block writes if rules lack makor:
Solution: Add makor facts for all normative rules.
Unknown World Reference¶
Solution: Check spelling against VALID_WORLDS.
Override Third Argument¶
Solution: Use descriptive new value, e.g., no_sakana instead of invalid.
Related Documentation¶
- Corpus Preparation - Previous phase
- Validation Skill - Next phase
- Predicate Registry - Available predicates
- HLL Language Reference - Syntax guide