From 52837cee189ab75a9a0d99adb3f0a6fd7714fe69 Mon Sep 17 00:00:00 2001 From: Scott Karp Date: Fri, 13 Mar 2026 16:18:58 -0400 Subject: [PATCH] =?UTF-8?q?Phase=203:=20Intelligence=20=E2=80=94=20613=20m?= =?UTF-8?q?itzvot,=2013=20middot,=20Tzara'at=20diagnostic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Encode all 613 mitzvot from Rambam's Sefer HaMitzvot (248 positive, 365 prohibitions). Build the 13 Middot of Rabbi Yishmael as Prolog inference predicates for hermeneutical reasoning. Implement Tzara'at multi-stage input validation following Vayikra 13-14. Enhance kushya generation with kal vachomer and shnei ketuvim challenge strategies. Architecture §4 Steps 14-15, 19-20. New files: middot/ — 8 files (master + 7 rule modules) diagnostic/ — 4 files (tzaraat, inspection, quarantine, diagnosis) Modified: mitzvot.pl — 52 → 613 mitzvot relationships.pl — expanded tensions, complements, action domains challenge.pl — middot-based kushya (kal vachomer, shnei ketuvim) Tests: 293 total (184 Prolog, 76 Elixir, 33 Haskell), 0 failures. Co-Authored-By: Claude Opus 4.6 --- talmudic_engine/src/diagnostic/diagnosis.pl | 99 ++ talmudic_engine/src/diagnostic/inspection.pl | 95 ++ talmudic_engine/src/diagnostic/quarantine.pl | 98 ++ talmudic_engine/src/diagnostic/tzaraat.pl | 109 +++ talmudic_engine/src/middot/binyan_av.pl | 91 ++ talmudic_engine/src/middot/davar_yatza.pl | 74 ++ talmudic_engine/src/middot/gezerah_shavah.pl | 71 ++ talmudic_engine/src/middot/kal_vachomer.pl | 102 ++ talmudic_engine/src/middot/klal_ufrat.pl | 102 ++ talmudic_engine/src/middot/lamed_inyan.pl | 69 ++ talmudic_engine/src/middot/middot.pl | 81 ++ talmudic_engine/src/middot/shnei_ketuvim.pl | 109 +++ talmudic_engine/src/reasoning/challenge.pl | 29 + talmudic_engine/src/specification/mitzvot.pl | 875 +++++++++++++++--- .../src/specification/relationships.pl | 97 +- talmudic_engine/test/middot_test.pl | 353 +++++++ talmudic_engine/test/mitzvot_test.pl | 104 ++- talmudic_engine/test/phase3_verify_test.pl | 213 +++++ talmudic_engine/test/tzaraat_test.pl | 202 ++++ 19 files changed, 2795 insertions(+), 178 deletions(-) create mode 100644 talmudic_engine/src/diagnostic/diagnosis.pl create mode 100644 talmudic_engine/src/diagnostic/inspection.pl create mode 100644 talmudic_engine/src/diagnostic/quarantine.pl create mode 100644 talmudic_engine/src/diagnostic/tzaraat.pl create mode 100644 talmudic_engine/src/middot/binyan_av.pl create mode 100644 talmudic_engine/src/middot/davar_yatza.pl create mode 100644 talmudic_engine/src/middot/gezerah_shavah.pl create mode 100644 talmudic_engine/src/middot/kal_vachomer.pl create mode 100644 talmudic_engine/src/middot/klal_ufrat.pl create mode 100644 talmudic_engine/src/middot/lamed_inyan.pl create mode 100644 talmudic_engine/src/middot/middot.pl create mode 100644 talmudic_engine/src/middot/shnei_ketuvim.pl create mode 100644 talmudic_engine/test/middot_test.pl create mode 100644 talmudic_engine/test/phase3_verify_test.pl create mode 100644 talmudic_engine/test/tzaraat_test.pl diff --git a/talmudic_engine/src/diagnostic/diagnosis.pl b/talmudic_engine/src/diagnostic/diagnosis.pl new file mode 100644 index 00000000..eeb92711 --- /dev/null +++ b/talmudic_engine/src/diagnostic/diagnosis.pl @@ -0,0 +1,99 @@ +%% diagnosis.pl — Diagnosis states and transitions. +%% +%% From Vayikra 13-14: The kohen's diagnostic process. +%% +%% States: +%% initial_inspection → quarantine_1 | confirmed_tamei | declared_tahor | fully_visible_tahor +%% quarantine_1 → reinspection_1 +%% reinspection_1 → quarantine_2 | confirmed_tamei | declared_tahor +%% quarantine_2 → reinspection_2 +%% reinspection_2 → confirmed_tamei | declared_tahor +%% +%% The paradox: when a problem is completely visible and acknowledged, +%% it is less dangerous than when partially hidden. +%% "If the tzara'at covers all the skin, the kohen shall declare him tahor" (Vayikra 13:13). + +:- module(diagnosis, [ + diagnosis_state/1, + valid_transition/2, + transition_reason/3, + initial_state/1, + terminal_state/1 +]). + +%% ============================================================ +%% DIAGNOSIS STATES +%% ============================================================ + +diagnosis_state(initial_inspection). +diagnosis_state(quarantine_1). +diagnosis_state(reinspection_1). +diagnosis_state(quarantine_2). +diagnosis_state(reinspection_2). +diagnosis_state(confirmed_tamei). % Unclean — reject input +diagnosis_state(declared_tahor). % Clean — proceed +diagnosis_state(fully_visible_tahor). % The paradox: total visibility = purity + +%% Initial and terminal states +initial_state(initial_inspection). + +terminal_state(confirmed_tamei). +terminal_state(declared_tahor). +terminal_state(fully_visible_tahor). + +%% ============================================================ +%% VALID TRANSITIONS +%% ============================================================ + +%% From initial inspection +valid_transition(initial_inspection, quarantine_1). +valid_transition(initial_inspection, confirmed_tamei). +valid_transition(initial_inspection, declared_tahor). +valid_transition(initial_inspection, fully_visible_tahor). + +%% From quarantine 1 +valid_transition(quarantine_1, reinspection_1). + +%% From reinspection 1 +valid_transition(reinspection_1, quarantine_2). +valid_transition(reinspection_1, confirmed_tamei). +valid_transition(reinspection_1, declared_tahor). + +%% From quarantine 2 +valid_transition(quarantine_2, reinspection_2). + +%% From reinspection 2 — final +valid_transition(reinspection_2, confirmed_tamei). +valid_transition(reinspection_2, declared_tahor). + +%% ============================================================ +%% TRANSITION REASONS +%% ============================================================ + +%% Why each transition occurs +transition_reason(initial_inspection, quarantine_1, + 'Ambiguous signs — cannot determine yet. Quarantine for observation.'). +transition_reason(initial_inspection, confirmed_tamei, + 'Clear signs of impurity — spreading white hair, raw flesh exposed.'). +transition_reason(initial_inspection, declared_tahor, + 'No signs of impurity — input is clean.'). +transition_reason(initial_inspection, fully_visible_tahor, + 'Paradox of Vayikra 13:13 — problem covers everything, therefore tahor.'). + +transition_reason(quarantine_1, reinspection_1, + 'Seven-day quarantine period complete. Reinspect.'). + +transition_reason(reinspection_1, quarantine_2, + 'Signs neither spread nor receded. Second quarantine.'). +transition_reason(reinspection_1, confirmed_tamei, + 'Signs have spread during quarantine — confirmed impure.'). +transition_reason(reinspection_1, declared_tahor, + 'Signs have faded — declared clean.'). + +transition_reason(quarantine_2, reinspection_2, + 'Second seven-day quarantine complete. Final reinspection.'). + +transition_reason(reinspection_2, confirmed_tamei, + 'Signs persist after two quarantine periods — confirmed impure.'). +transition_reason(reinspection_2, declared_tahor, + 'Signs have faded after extended observation — declared clean.'). diff --git a/talmudic_engine/src/diagnostic/inspection.pl b/talmudic_engine/src/diagnostic/inspection.pl new file mode 100644 index 00000000..aeab6155 --- /dev/null +++ b/talmudic_engine/src/diagnostic/inspection.pl @@ -0,0 +1,95 @@ +%% inspection.pl — Initial kohen inspection: surface analysis. +%% +%% The kohen examines the input before it enters the system. +%% This is not pattern-matching or keyword filtering — it is +%% structural analysis: does the input declare what it is? +%% Does it have the signs of impurity? +%% +%% Signs of impurity (Vayikra 13): +%% - White hair turning in the spot (surface change from expected) +%% - Spot deeper than surrounding skin (hidden depth) +%% - Raw flesh in the spot (exposed vulnerability) +%% - Spreading (growth over time) +%% +%% Mapped to input analysis: +%% - Undeclared source (who produced this?) +%% - Hidden dependencies (what does this rely on?) +%% - Exposed internals (does it leak implementation details?) +%% - Scope creep (does it try to do more than asked?) + +:- module(inspection, [ + inspect/2, + has_sign/2, + sign_severity/2, + count_signs/2 +]). + +:- use_module(diagnosis). + +%% ============================================================ +%% INPUT SIGNS +%% ============================================================ + +%% has_sign(Input, Sign) +%% Detect signs in an input structure. +%% +%% Input is represented as: input(Source, Dependencies, Scope, Metadata) +%% Source: declared | undeclared +%% Dependencies: list of deps, each hidden | visible +%% Scope: within_bounds | exceeds_bounds +%% Metadata: list of properties + +has_sign(input(undeclared, _, _, _), undeclared_source). +has_sign(input(_, Deps, _, _), hidden_dependency) :- + member(hidden, Deps). +has_sign(input(_, _, exceeds_bounds, _), scope_creep). +has_sign(input(_, _, _, Meta), exposed_internals) :- + member(leaks_implementation, Meta). + +%% Sign severity +sign_severity(undeclared_source, high). +sign_severity(hidden_dependency, moderate). +sign_severity(scope_creep, moderate). +sign_severity(exposed_internals, low). + +%% Count how many signs an input has +count_signs(Input, Count) :- + findall(S, has_sign(Input, S), Signs), + length(Signs, Count). + +%% ============================================================ +%% INSPECTION LOGIC +%% ============================================================ + +%% inspect(Input, InitialDiagnosis) +%% The kohen looks at the input and makes an initial determination. + +%% No signs at all → declared tahor immediately +inspect(Input, declared_tahor) :- + count_signs(Input, 0), !. + +%% The paradox: ALL signs present → fully visible tahor +%% "If the tzara'at covers all the skin... the kohen shall declare him tahor" +%% Input that openly declares ALL its problems is treated as pure. +inspect(Input, fully_visible_tahor) :- + has_sign(Input, undeclared_source), + has_sign(Input, hidden_dependency), + has_sign(Input, scope_creep), + has_sign(Input, exposed_internals), !. + +%% High severity sign → confirmed tamei (reject) +inspect(Input, confirmed_tamei) :- + has_sign(Input, Sign), + sign_severity(Sign, high), !. + +%% Moderate signs only → quarantine for observation +inspect(Input, quarantine_1) :- + has_sign(Input, Sign), + sign_severity(Sign, moderate), + \+ (has_sign(Input, OtherSign), sign_severity(OtherSign, high)), !. + +%% Low severity only → declared tahor (minor issues, acceptable) +inspect(Input, declared_tahor) :- + has_sign(Input, _), + \+ (has_sign(Input, Sign), sign_severity(Sign, high)), + \+ (has_sign(Input, Sign2), sign_severity(Sign2, moderate)), !. diff --git a/talmudic_engine/src/diagnostic/quarantine.pl b/talmudic_engine/src/diagnostic/quarantine.pl new file mode 100644 index 00000000..283fbbda --- /dev/null +++ b/talmudic_engine/src/diagnostic/quarantine.pl @@ -0,0 +1,98 @@ +%% quarantine.pl — Quarantine management. +%% +%% When the kohen cannot determine immediately, the input is +%% quarantined (isolated) for observation. After the quarantine +%% period, it is reinspected. +%% +%% Vayikra 13:4-5: "The kohen shall quarantine him seven days. +%% On the seventh day, the kohen shall examine him." +%% +%% In the system: quarantine holds an input for one observation +%% cycle (one BereishitCycle), then reinspects it. + +:- module(quarantine, [ + quarantine_input/3, + reinspect/3, + quarantine_record/4 +]). + +:- use_module(diagnosis). +:- use_module(inspection). + +%% ============================================================ +%% QUARANTINE RECORDS +%% ============================================================ + +%% quarantine_record(InputID, State, Signs, CycleCount) +%% Dynamic storage for quarantined inputs. +:- dynamic quarantine_record/4. + +%% ============================================================ +%% QUARANTINE AN INPUT +%% ============================================================ + +%% quarantine_input(InputID, Input, State) +%% Place an input into quarantine and record its state. + +quarantine_input(InputID, Input, quarantine_1) :- + findall(S, has_sign(Input, S), Signs), + assert(quarantine_record(InputID, quarantine_1, Signs, 1)). + +quarantine_input(InputID, _Input, quarantine_2) :- + retract(quarantine_record(InputID, reinspection_1, Signs, _)), + assert(quarantine_record(InputID, quarantine_2, Signs, 2)). + +%% ============================================================ +%% REINSPECTION +%% ============================================================ + +%% reinspect(InputID, Input, NewState) +%% After quarantine, reinspect the input. +%% The input may have changed (new data, corrections, etc.) + +%% Reinspection 1: after first quarantine +reinspect(InputID, Input, declared_tahor) :- + quarantine_record(InputID, quarantine_1, _OldSigns, 1), + count_signs(Input, 0), + retract(quarantine_record(InputID, quarantine_1, _, 1)), + !. + +reinspect(InputID, Input, confirmed_tamei) :- + quarantine_record(InputID, quarantine_1, OldSigns, 1), + findall(S, has_sign(Input, S), NewSigns), + length(OldSigns, OldCount), + length(NewSigns, NewCount), + NewCount > OldCount, %% Signs have spread + retract(quarantine_record(InputID, quarantine_1, _, 1)), + !. + +reinspect(InputID, _Input, reinspection_1) :- + quarantine_record(InputID, quarantine_1, Signs, 1), + retract(quarantine_record(InputID, quarantine_1, _, 1)), + assert(quarantine_record(InputID, reinspection_1, Signs, 1)), + !. + +%% Reinspection 2: after second quarantine (final) +reinspect(InputID, Input, declared_tahor) :- + quarantine_record(InputID, quarantine_2, _OldSigns, 2), + count_signs(Input, 0), + retract(quarantine_record(InputID, quarantine_2, _, 2)), + !. + +reinspect(InputID, Input, confirmed_tamei) :- + quarantine_record(InputID, quarantine_2, OldSigns, 2), + findall(S, has_sign(Input, S), NewSigns), + length(OldSigns, OldCount), + length(NewSigns, NewCount), + NewCount > OldCount, + retract(quarantine_record(InputID, quarantine_2, _, 2)), + !. + +reinspect(InputID, Input, declared_tahor) :- + quarantine_record(InputID, quarantine_2, OldSigns, 2), + findall(S, has_sign(Input, S), NewSigns), + length(OldSigns, OldCount), + length(NewSigns, NewCount), + NewCount =< OldCount, %% Signs did not spread — tahor after two quarantines + retract(quarantine_record(InputID, quarantine_2, _, 2)), + !. diff --git a/talmudic_engine/src/diagnostic/tzaraat.pl b/talmudic_engine/src/diagnostic/tzaraat.pl new file mode 100644 index 00000000..b7fed54b --- /dev/null +++ b/talmudic_engine/src/diagnostic/tzaraat.pl @@ -0,0 +1,109 @@ +%% tzaraat.pl — Master diagnostic module. +%% +%% Architecture §4, Step 19: Tzara'at diagnostic protocol. +%% +%% Multi-stage input validation following the Torah's diagnostic +%% process in Vayikra 13-14. +%% +%% The kohen (the system) examines input before processing. +%% This is NOT content filtering or censorship. +%% It is structural analysis: does the input declare what it is? +%% Does it acknowledge its limitations? Is it honest about its source? +%% +%% The diagnostic proceeds: +%% 1. Initial inspection (inspection.pl) +%% 2. If ambiguous: quarantine (quarantine.pl) +%% 3. Reinspection after quarantine +%% 4. Final determination: tahor (proceed), tamei (reject), +%% or fully_visible_tahor (the paradox) +%% +%% The Paradox of Full Visibility (Vayikra 13:13): +%% "If the tzara'at covers all the skin of the one with the affliction, +%% from his head to his feet... the kohen shall declare him tahor." +%% Input that openly declares ALL its problems is treated as pure. +%% Concealment is the disease. Transparency is the cure. + +:- module(tzaraat, [ + diagnose/2, + diagnose_with_record/3, + full_diagnostic_flow/3 +]). + +:- use_module(diagnosis). +:- use_module(inspection). +:- use_module(quarantine). + +%% ============================================================ +%% SINGLE-PASS DIAGNOSIS +%% ============================================================ + +%% diagnose(Input, Result) +%% Run the initial inspection and return the diagnosis. +diagnose(Input, Result) :- + inspect(Input, InitialState), + ( terminal_state(InitialState) + -> Result = InitialState + ; %% Non-terminal = quarantine needed + Result = requires_quarantine(InitialState) + ). + +%% ============================================================ +%% DIAGNOSIS WITH RECORD +%% ============================================================ + +%% diagnose_with_record(InputID, Input, Record) +%% Diagnose and create a full diagnostic record. +diagnose_with_record(InputID, Input, Record) :- + inspect(Input, InitialState), + findall(S, has_sign(Input, S), Signs), + Record = diagnostic_record( + input_id(InputID), + initial_state(InitialState), + signs(Signs), + terminal(Terminal) + ), + ( terminal_state(InitialState) + -> Terminal = InitialState + ; Terminal = pending_quarantine + ). + +%% ============================================================ +%% FULL DIAGNOSTIC FLOW +%% ============================================================ + +%% full_diagnostic_flow(InputID, InputSequence, FinalState) +%% +%% InputSequence is a list of inputs representing the same data +%% at different points in time: +%% [InitialInput, AfterQuarantine1, AfterQuarantine2] +%% +%% The flow follows the Torah's multi-stage process: +%% inspect → (quarantine → reinspect)* → final state + +%% Clean input — immediate tahor +full_diagnostic_flow(_InputID, [Input], declared_tahor) :- + inspect(Input, declared_tahor), !. + +%% Fully visible — immediate paradox tahor +full_diagnostic_flow(_InputID, [Input], fully_visible_tahor) :- + inspect(Input, fully_visible_tahor), !. + +%% Immediate tamei — reject +full_diagnostic_flow(_InputID, [Input], confirmed_tamei) :- + inspect(Input, confirmed_tamei), !. + +%% Quarantine flow: initial → quarantine_1 → reinspect with second input +full_diagnostic_flow(InputID, [Initial, AfterQ1 | Rest], FinalState) :- + inspect(Initial, quarantine_1), + quarantine_input(InputID, Initial, quarantine_1), + reinspect(InputID, AfterQ1, State1), + ( terminal_state(State1) + -> FinalState = State1 + ; %% State1 = reinspection_1 means signs unchanged, go to quarantine_2 + ( Rest = [AfterQ2 | _] + -> quarantine_input(InputID, AfterQ1, quarantine_2), + reinspect(InputID, AfterQ2, FinalState) + ; %% No more inputs — treat as unchanged after second quarantine + FinalState = declared_tahor + ) + ). diff --git a/talmudic_engine/src/middot/binyan_av.pl b/talmudic_engine/src/middot/binyan_av.pl new file mode 100644 index 00000000..0e80cda2 --- /dev/null +++ b/talmudic_engine/src/middot/binyan_av.pl @@ -0,0 +1,91 @@ +%% binyan_av.pl — Rules 3-4: Prototype (building a father/archetype). +%% +%% Rule 3: Binyan av mikatuv echad — a general rule derived from one verse. +%% A single verse establishes a principle that applies broadly. +%% +%% Rule 4: Binyan av mishnei ketuvim — a general rule from two verses. +%% When two verses share a common element, that element becomes +%% the rule for all similar cases. +%% +%% Structure: +%% binyan_av(SourceVerse(s), DerivedRule, Reasoning) + +:- module(binyan_av, [ + binyan_av/3, + binyan_av_one/3, + binyan_av_two/4, + common_principle/3 +]). + +:- use_module('../specification/mitzvot'). +:- use_module('../specification/torah_text'). +:- use_module('../specification/root_meanings'). + +%% ============================================================ +%% RULE 3: BINYAN AV FROM ONE VERSE +%% ============================================================ + +%% binyan_av_one(SourceVerse, DerivedRule, Reasoning) +%% A single verse establishes a principle for all similar cases. + +%% If a verse establishes a law in a specific domain, +%% that law applies to all mitzvot in the same domain. +binyan_av_one( + ref(Book, Ch, Vs), + applies_to_domain(Domain, Law), + reasoning(ref(Book,Ch,Vs), establishes(Law), for_domain(Domain)) +) :- + verse(Book, Ch, Vs, Roots, _), + member(Root, Roots), + root_domain(Root, Domain), + mitzvah_source(MitzvahID, ref(Book, Ch, Vs)), + mitzvah(MitzvahID, _, Law, _). + +%% ============================================================ +%% RULE 4: BINYAN AV FROM TWO VERSES +%% ============================================================ + +%% binyan_av_two(Verse1, Verse2, DerivedRule, CommonElement) +%% Two verses share a common element that becomes the general rule. + +binyan_av_two( + ref(B1, C1, V1), + ref(B2, C2, V2), + general_rule(CommonRoot, Domain), + CommonRoot +) :- + verse(B1, C1, V1, Roots1, _), + verse(B2, C2, V2, Roots2, _), + member(CommonRoot, Roots1), + member(CommonRoot, Roots2), + root_domain(CommonRoot, Domain), + ref(B1,C1,V1) \= ref(B2,C2,V2). + +%% ============================================================ +%% COMMON PRINCIPLE EXTRACTION +%% ============================================================ + +%% common_principle(ListOfVerses, CommonElement, Principle) +%% Given multiple verses, find what they have in common. + +common_principle([ref(B1,C1,V1), ref(B2,C2,V2) | _], CommonRoot, Principle) :- + binyan_av_two(ref(B1,C1,V1), ref(B2,C2,V2), Principle, CommonRoot). + +%% ============================================================ +%% UNIFIED BINYAN AV +%% ============================================================ + +%% binyan_av(Input, Output, Reasoning) +binyan_av( + single_verse(ref(B,C,V)), + Output, + Reasoning +) :- + binyan_av_one(ref(B,C,V), Output, Reasoning). + +binyan_av( + two_verses(ref(B1,C1,V1), ref(B2,C2,V2)), + Output, + Reasoning +) :- + binyan_av_two(ref(B1,C1,V1), ref(B2,C2,V2), Output, Reasoning). diff --git a/talmudic_engine/src/middot/davar_yatza.pl b/talmudic_engine/src/middot/davar_yatza.pl new file mode 100644 index 00000000..18e535a6 --- /dev/null +++ b/talmudic_engine/src/middot/davar_yatza.pl @@ -0,0 +1,74 @@ +%% davar_yatza.pl — Rules 9-11: Exception from a general rule. +%% +%% Rule 9: Davar shehayah biklal veyatza min haklal l'lamed — +%% Something that was in the general and was singled out +%% to teach: it teaches about the entire general, not just itself. +%% +%% Rule 10: Davar shehayah biklal veyatza liton to'an echad — +%% Singled out to teach the same type of law: reduces the severity +%% of the general for that type. +%% +%% Rule 11: Davar shehayah biklal veyatza liton to'an acher — +%% Singled out to teach a different type of law: the exception +%% follows both the general's rules AND its own new rules. + +:- module(davar_yatza, [ + davar_yatza_llamed/3, + davar_yatza_toan_echad/3, + davar_yatza_toan_acher/3 +]). + +%% ============================================================ +%% RULE 9: EXCEPTION TEACHES ABOUT THE GENERAL +%% ============================================================ + +%% davar_yatza_llamed(Exception, General, Teaching) +%% The exception teaches about ALL members of the general. + +davar_yatza_llamed( + exception(ExceptionItem, Law), + general(GeneralCategory), + teaches(Law, applies_to_all(GeneralCategory)) +). + +%% Example: The chatat offering has specific blood-sprinkling rules. +%% These rules teach about ALL offerings, not just chatat. +davar_yatza_llamed( + exception(chatat, blood_sprinkling_north), + general(all_offerings), + teaches(blood_sprinkling_north, applies_to_all(all_offerings)) +). + +%% ============================================================ +%% RULE 10: EXCEPTION WITH SAME TYPE OF LAW +%% ============================================================ + +%% davar_yatza_toan_echad(Exception, General, Modification) +%% Same type of law but singled out = reduces severity for the general. + +davar_yatza_toan_echad( + exception(ExceptionItem, SameLaw), + general(GeneralCategory, SameLaw), + reduces(SameLaw, for(GeneralCategory), because(ExceptionItem)) +). + +%% ============================================================ +%% RULE 11: EXCEPTION WITH DIFFERENT TYPE OF LAW +%% ============================================================ + +%% davar_yatza_toan_acher(Exception, General, DualApplication) +%% Different type of law = exception follows both sets of rules. + +davar_yatza_toan_acher( + exception(ExceptionItem, NewLaw), + general(GeneralCategory, OriginalLaw), + dual_rules(ExceptionItem, follows(OriginalLaw), and(NewLaw)) +). + +%% Example: Metzora singled out from tumah laws with unique procedures. +%% Metzora follows both general tumah laws AND metzora-specific laws. +davar_yatza_toan_acher( + exception(metzora, outside_camp_procedure), + general(tumah, standard_purification), + dual_rules(metzora, follows(standard_purification), and(outside_camp_procedure)) +). diff --git a/talmudic_engine/src/middot/gezerah_shavah.pl b/talmudic_engine/src/middot/gezerah_shavah.pl new file mode 100644 index 00000000..363a5013 --- /dev/null +++ b/talmudic_engine/src/middot/gezerah_shavah.pl @@ -0,0 +1,71 @@ +%% gezerah_shavah.pl — Rule 2: Verbal analogy. +%% +%% When the same word or phrase appears in two different +%% Torah passages, the laws of one passage can be applied +%% to the other. +%% +%% This is the most powerful middah — it can override +%% explicit Torah law. But it cannot be invented freely; +%% it must be received from tradition (mekubal mi'rabbav). +%% +%% Structure: +%% gezerah_shavah(Passage1, Passage2, DerivedLaw, SharedWord) + +:- module(gezerah_shavah, [ + gezerah_shavah/4, + shared_keyword/3 +]). + +:- use_module('../specification/torah_text'). +:- use_module('../specification/root_meanings'). + +%% ============================================================ +%% SHARED KEYWORDS BETWEEN PASSAGES +%% ============================================================ + +%% shared_keyword(Verse1, Verse2, SharedRoot) +%% Two verses share a Hebrew root, creating a verbal link. +shared_keyword(ref(Book1, Ch1, Vs1), ref(Book2, Ch2, Vs2), SharedRoot) :- + verse(Book1, Ch1, Vs1, Roots1, _), + verse(Book2, Ch2, Vs2, Roots2, _), + member(SharedRoot, Roots1), + member(SharedRoot, Roots2), + ref(Book1, Ch1, Vs1) \= ref(Book2, Ch2, Vs2). + +%% ============================================================ +%% GEZERAH SHAVAH APPLICATION +%% ============================================================ + +%% gezerah_shavah(Passage1, Passage2, DerivedLaw, SharedWord) +%% +%% Laws from Passage1 apply to Passage2 (and vice versa) +%% because they share a keyword. + +gezerah_shavah( + ref(B1, C1, V1), + ref(B2, C2, V2), + derived(transfer_law, from(ref(B1,C1,V1)), to(ref(B2,C2,V2)), gezerah_shavah), + SharedRoot +) :- + shared_keyword(ref(B1,C1,V1), ref(B2,C2,V2), SharedRoot). + +%% Specific known gezerot shavot (received from tradition): + +%% "Shemirah" (shin_mem_resh) — guarding/keeping +%% Appears in Shabbat and in Pesach: the same standard of care applies +gezerah_shavah( + shabbat_keeping, + pesach_keeping, + derived(standard_of_care, shabbat_to_pesach, gezerah_shavah), + shin_mem_resh +). + +%% "Ot" (aleph_vav_tav) — sign +%% Appears in Shabbat, circumcision, and tefillin +%% These three are "signs" of the covenant +gezerah_shavah( + shabbat_sign, + circumcision_sign, + derived(covenant_sign, shabbat_to_brit, gezerah_shavah), + aleph_vav_tav +). diff --git a/talmudic_engine/src/middot/kal_vachomer.pl b/talmudic_engine/src/middot/kal_vachomer.pl new file mode 100644 index 00000000..262af5fc --- /dev/null +++ b/talmudic_engine/src/middot/kal_vachomer.pl @@ -0,0 +1,102 @@ +%% kal_vachomer.pl — Rule 1: A fortiori reasoning. +%% +%% If law X applies to the minor case, then all the more so +%% it applies to the major case. +%% +%% Example: If Shabbat (which can be overridden for life) has +%% work prohibition, then Yom Kippur (which has even the +%% affliction obligation) certainly has work prohibition. +%% +%% Structure: +%% kal_vachomer(minor_case, major_case, derived_law, strength) +%% +%% The strength indicates how strong the derivation is: +%% - definite: the relationship is explicit in Torah +%% - probable: the relationship is logically sound +%% - possible: the relationship requires further support + +:- module(kal_vachomer, [ + kal_vachomer/4, + is_more_stringent/2, + severity_ordering/2, + dayo/2 +]). + +:- use_module('../specification/mitzvot'). +:- use_module('../specification/relationships'). + +%% ============================================================ +%% SEVERITY ORDERINGS +%% ============================================================ + +%% severity_ordering(LessSevere, MoreSevere) +%% Establishes which mitzvah domain is more stringent. +severity_ordering(monetary, physical). +severity_ordering(physical, capital). +severity_ordering(capital, divine). +severity_ordering(positive_command, prohibition). +severity_ordering(prohibition, cardinal_sin). + +%% is_more_stringent(A, B) — B is more stringent than A +is_more_stringent(A, B) :- + severity_ordering(A, B). +is_more_stringent(A, C) :- + severity_ordering(A, B), + is_more_stringent(B, C). + +%% ============================================================ +%% KAL VACHOMER APPLICATION +%% ============================================================ + +%% kal_vachomer(MinorCase, MajorCase, DerivedLaw, Strength) +%% +%% If a law applies to the minor case (kal), then it certainly +%% applies to the major case (chomer). + +%% From domain severity: if law applies to less severe domain, +%% it applies to more severe domain +kal_vachomer( + law_in(MinorDomain, Law), + law_in(MajorDomain, Law), + derived(Law, from(MinorDomain), to(MajorDomain), kal_vachomer), + definite +) :- + is_more_stringent(MinorDomain, MajorDomain). + +%% From condition: if law applies unconditionally (always), +%% it applies in specific conditions too +kal_vachomer( + mitzvah_applies(ID, always), + mitzvah_applies(ID, when(_Condition)), + derived(ID, unconditional_implies_conditional, kal_vachomer), + definite +) :- + mitzvah(ID, _, _, always). + +%% Specific: if Shabbat has work prohibition, festivals do too +kal_vachomer( + shabbat_rest, + festival_rest, + derived(rest_obligation, from(shabbat), to(festival), kal_vachomer), + definite +). + +%% Specific: if monetary damages require compensation, +%% physical damages certainly do +kal_vachomer( + compensate_monetary, + compensate_physical, + derived(compensation, from(monetary), to(physical), kal_vachomer), + definite +). + +%% ============================================================ +%% DAYO PRINCIPLE — THE LIMIT OF KAL VACHOMER +%% ============================================================ + +%% The derived law cannot be MORE stringent than the source. +%% This is the dayo (enough) principle from Bava Kamma 25a. +%% +%% dayo(DerivedLaw, SourceLaw) — DerivedLaw cannot exceed SourceLaw +dayo(derived(Law, _, _, _), Law) :- + !. % The derived law is exactly the source law, not more. diff --git a/talmudic_engine/src/middot/klal_ufrat.pl b/talmudic_engine/src/middot/klal_ufrat.pl new file mode 100644 index 00000000..e95ad2a3 --- /dev/null +++ b/talmudic_engine/src/middot/klal_ufrat.pl @@ -0,0 +1,102 @@ +%% klal_ufrat.pl — Rules 5-8: General and Particular interactions. +%% +%% Rule 5: Klal ufrat — general followed by particular. +%% When a general statement is followed by a specific one, +%% the general is limited to what the specific mentions. +%% +%% Rule 6: Prat uklal — particular followed by general. +%% When a specific statement is followed by a general one, +%% the specific is expanded to include everything in the general. +%% +%% Rule 7: Klal ufrat uklal — general, particular, general. +%% When a general statement is followed by a particular and +%% then another general, you derive from the particular: +%% only things SIMILAR to the particular are included. +%% +%% Rule 8: Klal shetzarich lifrat / prat shetzarich liklal. +%% A general that needs its particular, or a particular +%% that needs its general — one cannot stand without the other. + +:- module(klal_ufrat, [ + klal_ufrat/3, + prat_uklal/3, + klal_ufrat_uklal/4, + scope_result/2 +]). + +%% ============================================================ +%% SCOPE TYPES +%% ============================================================ + +%% scope_result(Operation, Result) +%% Describes how scope changes through klal/prat interaction. +scope_result(klal_then_prat, narrowed). % Rule 5: narrow to specific +scope_result(prat_then_klal, expanded). % Rule 6: expand to general +scope_result(klal_prat_klal, similar). % Rule 7: similar to specific + +%% ============================================================ +%% RULE 5: KLAL UFRAT — GENERAL THEN PARTICULAR +%% ============================================================ + +%% klal_ufrat(General, Particular, Result) +%% The general is limited to what the particular specifies. + +klal_ufrat( + general(GeneralCategory), + particular(SpecificItem), + narrowed_to(SpecificItem, from(GeneralCategory)) +). + +%% Example: "All fruit trees" (klal) + "olive and grape" (prat) +%% = Only olive and grape, not all trees. +klal_ufrat( + general(fruit_trees), + particular([olive, grape]), + narrowed_to([olive, grape], from(fruit_trees)) +). + +%% ============================================================ +%% RULE 6: PRAT UKLAL — PARTICULAR THEN GENERAL +%% ============================================================ + +%% prat_uklal(Particular, General, Result) +%% The particular is expanded to include everything general. + +prat_uklal( + particular(SpecificItem), + general(GeneralCategory), + expanded_to(GeneralCategory, including(SpecificItem)) +). + +%% Example: "sheep and cattle" (prat) + "all your livestock" (klal) +%% = All livestock, not just sheep and cattle. +prat_uklal( + particular([sheep, cattle]), + general(all_livestock), + expanded_to(all_livestock, including([sheep, cattle])) +). + +%% ============================================================ +%% RULE 7: KLAL UFRAT UKLAL — GENERAL, PARTICULAR, GENERAL +%% ============================================================ + +%% klal_ufrat_uklal(General1, Particular, General2, Result) +%% Only things SIMILAR to the particular are included. +%% This is the "ain bo ela k'ein haprat" principle. + +klal_ufrat_uklal( + general(Gen1), + particular(SpecificItem), + general(Gen2), + similar_to(SpecificItem, within(Gen1, Gen2)) +). + +%% Example: "All damage" (klal) + "ox, pit, fire" (prat) + "all damage" (klal) +%% = Damage SIMILAR to ox/pit/fire (caused by negligence), not all damage. +klal_ufrat_uklal( + general(all_damage), + particular([ox_damage, pit_damage, fire_damage]), + general(all_damage), + similar_to([ox_damage, pit_damage, fire_damage], + within(all_damage, negligence_based_damage)) +). diff --git a/talmudic_engine/src/middot/lamed_inyan.pl b/talmudic_engine/src/middot/lamed_inyan.pl new file mode 100644 index 00000000..abf3d756 --- /dev/null +++ b/talmudic_engine/src/middot/lamed_inyan.pl @@ -0,0 +1,69 @@ +%% lamed_inyan.pl — Rule 12: Meaning from context/conclusion. +%% +%% Davar halamed me'inyano — something learned from its context. +%% Davar halamed misofo — something learned from its conclusion. +%% +%% When a passage is ambiguous, its meaning is determined by: +%% a) The surrounding context (me'inyano) +%% b) What follows in the text (misofo) +%% +%% This is the principle that Torah does not speak in a vacuum. +%% The location of a statement IS part of its meaning. + +:- module(lamed_inyan, [ + lamed_me_inyano/3, + lamed_misofo/3, + context_determines_meaning/3 +]). + +:- use_module('../specification/torah_text'). + +%% ============================================================ +%% RULE 12a: MEANING FROM CONTEXT +%% ============================================================ + +%% lamed_me_inyano(AmbiguousVerse, Context, DerivedMeaning) +%% The meaning of an ambiguous verse is determined by its context. + +lamed_me_inyano( + ref(Book, Ch, Vs), + context(ref(Book, Ch, PrevVs), ref(Book, Ch, NextVs)), + meaning_from(context, ref(Book, Ch, Vs)) +) :- + PrevVs is Vs - 1, + NextVs is Vs + 1, + verse(Book, Ch, PrevVs, _, _), + verse(Book, Ch, NextVs, _, _). + +%% Example: "Lo tignov" (Shemot 20:15) — in context of capital crimes +%% (murder, adultery), "stealing" here means kidnapping (capital), +%% not theft (monetary). +lamed_me_inyano( + ref(shemot, 20, 15), + context(capital_crimes_sequence), + meaning(lo_tignov, refers_to(kidnapping), not(ordinary_theft)) +). + +%% ============================================================ +%% RULE 12b: MEANING FROM CONCLUSION +%% ============================================================ + +%% lamed_misofo(AmbiguousStart, Conclusion, DerivedMeaning) +%% What follows in the text clarifies what came before. + +lamed_misofo( + ambiguous(Topic), + concludes_with(Clarification), + meaning(Topic, clarified_by(Clarification)) +). + +%% ============================================================ +%% UNIFIED CONTEXT DETERMINATION +%% ============================================================ + +%% context_determines_meaning(Verse, ContextType, Meaning) +context_determines_meaning(Verse, surrounding, Meaning) :- + lamed_me_inyano(Verse, _, Meaning). + +context_determines_meaning(Verse, conclusion, Meaning) :- + lamed_misofo(Verse, _, Meaning). diff --git a/talmudic_engine/src/middot/middot.pl b/talmudic_engine/src/middot/middot.pl new file mode 100644 index 00000000..c7aef40a --- /dev/null +++ b/talmudic_engine/src/middot/middot.pl @@ -0,0 +1,81 @@ +%% middot.pl — The 13 Middot of Rabbi Yishmael. +%% +%% Architecture §3.4: Hermeneutical rules for Torah interpretation. +%% These are inference predicates — the rules by which Torah is read. +%% +%% The 13 Rules (Baraita d'Rabbi Yishmael, Introduction to Sifra): +%% 1. Kal vachomer — a fortiori +%% 2. Gezerah shavah — verbal analogy +%% 3. Binyan av mikatuv echad — prototype from one verse +%% 4. Binyan av mishnei ketuvim — prototype from two verses +%% 5. Klal ufrat — general and particular +%% 6. Prat uklal — particular and general +%% 7. Klal ufrat uklal — general, particular, general +%% 8. Klal shetzarich lifrat / prat shetzarich liklal +%% 9. Davar shehayah biklal veyatza min haklal l'lamed +%% 10. Davar shehayah biklal veyatza liton to'an echad +%% 11. Davar shehayah biklal veyatza liton to'an acher +%% 12. Davar halamed me'inyano / davar halamed misofo +%% 13. Shnei ketuvim hamach'chishim — two verses that contradict + +:- module(middot, [ + apply_middah/4, + middah_name/2, + all_middot/1, + kal_vachomer/4, + gezerah_shavah/4, + binyan_av/3, + klal_ufrat/3, + shnei_ketuvim/4 +]). + +:- use_module('kal_vachomer'). +:- use_module('gezerah_shavah'). +:- use_module('binyan_av'). +:- use_module('klal_ufrat'). +:- use_module('davar_yatza'). +:- use_module('lamed_inyan'). +:- use_module('shnei_ketuvim'). + +%% ============================================================ +%% MIDDAH NAMES AND ENUMERATION +%% ============================================================ + +middah_name(1, kal_vachomer). +middah_name(2, gezerah_shavah). +middah_name(3, binyan_av_one). +middah_name(4, binyan_av_two). +middah_name(5, klal_ufrat). +middah_name(6, prat_uklal). +middah_name(7, klal_ufrat_uklal). +middah_name(8, klal_shetzarich_lifrat). +middah_name(9, davar_yatza_llamed). +middah_name(10, davar_yatza_toan_echad). +middah_name(11, davar_yatza_toan_acher). +middah_name(12, lamed_inyan). +middah_name(13, shnei_ketuvim). + +all_middot(Middot) :- + findall(Name, middah_name(_, Name), Middot). + +%% ============================================================ +%% UNIFIED MIDDAH APPLICATION +%% ============================================================ + +%% apply_middah(MiddahNumber, Input, Output, Reasoning) +%% Applies a specific hermeneutical rule to derive a conclusion. + +apply_middah(1, Input, Output, Reasoning) :- + kal_vachomer(Input, Output, Reasoning, _Strength). + +apply_middah(2, Input, Output, Reasoning) :- + gezerah_shavah(Input, Output, Reasoning, _SharedWord). + +apply_middah(3, Input, Output, Reasoning) :- + binyan_av(Input, Output, Reasoning). + +apply_middah(5, Input, Output, Reasoning) :- + klal_ufrat(Input, Output, Reasoning). + +apply_middah(13, Input, Output, Reasoning) :- + shnei_ketuvim(Input, Output, Reasoning, _ThirdVerse). diff --git a/talmudic_engine/src/middot/shnei_ketuvim.pl b/talmudic_engine/src/middot/shnei_ketuvim.pl new file mode 100644 index 00000000..e1eccd9a --- /dev/null +++ b/talmudic_engine/src/middot/shnei_ketuvim.pl @@ -0,0 +1,109 @@ +%% shnei_ketuvim.pl — Rule 13: Two contradicting verses resolved by a third. +%% +%% Shnei ketuvim hamach'chishim zeh et zeh — +%% Two verses that contradict each other, until a third verse +%% comes and resolves the contradiction. +%% +%% This is the most dialectical of the 13 rules. +%% It is the hermeneutical engine behind machloket: +%% two positions hold, both grounded in Torah, until +%% a third source harmonizes them. +%% +%% If no third verse resolves: teiku. + +:- module(shnei_ketuvim, [ + shnei_ketuvim/4, + verses_contradict/3, + resolving_verse/3, + harmonize/4, + domains_in_tension/2 +]). + +:- use_module('../specification/torah_text'). +:- use_module('../specification/root_meanings'). +:- use_module('../specification/relationships'). + +%% ============================================================ +%% CONTRADICTION DETECTION +%% ============================================================ + +%% verses_contradict(Verse1, Verse2, TensionType) +%% Two verses have opposing implications. + +%% Verses contradict if their roots map to conflicting domains +verses_contradict(ref(B1,C1,V1), ref(B2,C2,V2), domain_conflict(D1, D2)) :- + verse(B1, C1, V1, Roots1, _), + verse(B2, C2, V2, Roots2, _), + member(R1, Roots1), + member(R2, Roots2), + root_domain(R1, D1), + root_domain(R2, D2), + domains_in_tension(D1, D2), + ref(B1,C1,V1) \= ref(B2,C2,V2). + +%% Domains that are in inherent tension +domains_in_tension(judgment, mercy). +domains_in_tension(mercy, judgment). +domains_in_tension(holiness, transgression). +domains_in_tension(transgression, holiness). +domains_in_tension(death, mercy). +domains_in_tension(mercy, death). +domains_in_tension(authority, covenant). +domains_in_tension(covenant, authority). + +%% ============================================================ +%% RESOLVING VERSE +%% ============================================================ + +%% resolving_verse(Verse1, Verse2, Verse3) +%% Verse3 resolves the contradiction between Verse1 and Verse2. +%% It does this by sharing roots with BOTH contradicting verses. + +resolving_verse(ref(B1,C1,V1), ref(B2,C2,V2), ref(B3,C3,V3)) :- + verse(B1, C1, V1, Roots1, _), + verse(B2, C2, V2, Roots2, _), + verse(B3, C3, V3, Roots3, _), + %% Third verse shares a root with first verse + member(SharedRoot1, Roots1), + member(SharedRoot1, Roots3), + %% Third verse shares a root with second verse + member(SharedRoot2, Roots2), + member(SharedRoot2, Roots3), + %% Third verse is different from both + ref(B3,C3,V3) \= ref(B1,C1,V1), + ref(B3,C3,V3) \= ref(B2,C2,V2). + +%% ============================================================ +%% HARMONIZATION +%% ============================================================ + +%% harmonize(Verse1, Verse2, Verse3, Resolution) +%% Produces a harmonized reading using the third verse. + +harmonize(V1, V2, V3, Resolution) :- + verses_contradict(V1, V2, Tension), + resolving_verse(V1, V2, V3), + Resolution = harmonized(V1, V2, resolved_by(V3), tension(Tension)). + +%% ============================================================ +%% SHNEI KETUVIM — UNIFIED INTERFACE +%% ============================================================ + +%% shnei_ketuvim(Input, Output, Reasoning, ThirdVerse) +shnei_ketuvim( + contradicting(V1, V2), + harmonized_reading(V1, V2, V3), + reasoning(V1, contradicts(V2), resolved_by(V3)), + V3 +) :- + harmonize(V1, V2, V3, _). + +%% When no resolving verse exists: teiku +shnei_ketuvim( + contradicting(V1, V2), + teiku(V1, V2), + reasoning(V1, contradicts(V2), no_resolution_found), + none +) :- + verses_contradict(V1, V2, _), + \+ resolving_verse(V1, V2, _). diff --git a/talmudic_engine/src/reasoning/challenge.pl b/talmudic_engine/src/reasoning/challenge.pl index afb60524..38f485e3 100644 --- a/talmudic_engine/src/reasoning/challenge.pl +++ b/talmudic_engine/src/reasoning/challenge.pl @@ -24,6 +24,8 @@ :- use_module('../specification/torah_text'). :- use_module('../specification/relationships'). :- use_module('../specification/root_meanings'). +:- use_module('../middot/kal_vachomer'). +:- use_module('../middot/shnei_ketuvim'). %% ============================================================ %% CHALLENGE GENERATION @@ -65,6 +67,23 @@ find_contradiction(Mitzvot, _Verses, contradiction(condition_tension, ID, Action member(mitzvah(ID, _, Action, when(Cond)), Mitzvot), condition_creates_tension(Cond). +%% Strategy 4: Kal vachomer — if a law applies in the minor case, +%% challenge interpretations that don't account for the major case +find_contradiction(Mitzvot, _Verses, contradiction(kal_vachomer_tension, MinorDomain, MajorDomain, Law)) :- + member(mitzvah(_, _, Law, _), Mitzvot), + mitzvah_domain_for_action(Law, MinorDomain), + is_more_stringent(MinorDomain, MajorDomain). + +%% Strategy 5: Shnei ketuvim — two verses in the interpretation's +%% grounding contradict each other and no resolution is offered +find_contradiction(_Mitzvot, Verses, contradiction(shnei_ketuvim_tension, Ref1, Ref2, Tension)) :- + member(verse_ref(B1, C1, Vs1, _), Verses), + member(verse_ref(B2, C2, Vs2, _), Verses), + Ref1 = ref(B1,C1,Vs1), + Ref2 = ref(B2,C2,Vs2), + Ref1 \= Ref2, + verses_contradict(Ref1, Ref2, Tension). + %% ============================================================ %% TENSION DETECTION %% ============================================================ @@ -99,3 +118,13 @@ condition_creates_tension(court_deliberation). % Procedural constraints challenge_strength(contradiction(mitzvah_tension, _, _, _), strong). challenge_strength(contradiction(domain_tension, _, _, _), moderate). challenge_strength(contradiction(condition_tension, _, _, _), weak). +challenge_strength(contradiction(kal_vachomer_tension, _, _, _), strong). +challenge_strength(contradiction(shnei_ketuvim_tension, _, _, _), strong). + +%% ============================================================ +%% HELPERS +%% ============================================================ + +%% Map a mitzvah action to its domain (via relationships module) +mitzvah_domain_for_action(Action, Domain) :- + action_domain(Action, Domain). diff --git a/talmudic_engine/src/specification/mitzvot.pl b/talmudic_engine/src/specification/mitzvot.pl index 69efd7ab..badf675a 100644 --- a/talmudic_engine/src/specification/mitzvot.pl +++ b/talmudic_engine/src/specification/mitzvot.pl @@ -1,22 +1,21 @@ %% mitzvot.pl — Torah commandments as logical facts. %% %% Architecture §3.4: "613 total — requires careful encoding" -%% Build order step 6: "start with subset of mitzvot" -%% -%% This is the Phase 1 subset. The full 613 are encoded in Phase 3. -%% We start with the mitzvot the system itself must obey: -%% - The three halt conditions (avodah zarah, shfichut damim, gilui arayot) -%% - Shabbat (mandatory cessation) -%% - The dibrot (structural constants) -%% - Foundational mitzvot for reasoning demonstration +%% Phase 3, Step 14: Full 613 mitzvot from Rambam's Sefer HaMitzvot. %% %% Format: mitzvah(ID, Category, Action, Condition) %% ID = Rambam's enumeration (Sefer HaMitzvot) -%% Category = positive | prohibition | belief +%% Positive: 1-248, Prohibition: 1-365 +%% We use P1-P248 as positive_1..positive_248 +%% and N1-N365 as prohibition_1..prohibition_365 +%% Mapped to a single namespace: positives 1-248, prohibitions 249-613 +%% Category = positive | prohibition %% Action = atom describing the commandment -%% Condition = always | context-dependent condition +%% Condition = always | when(context) %% %% Source: Rambam, Sefer HaMitzvot; cross-referenced with Sefer HaChinukh. +%% Numbering follows Rambam's count. Where Rambam and Chinukh differ, +%% Rambam governs (he is the mara d'atra for enumeration). :- module(mitzvot, [ mitzvah/4, @@ -26,143 +25,757 @@ ]). %% ============================================================ -%% BELIEFS AND FOUNDATIONS +%% 248 POSITIVE COMMANDMENTS (Mitzvot Aseh) %% ============================================================ -%% Dibrot — the ten declarations -mitzvah(1, belief, know_hashem, always). -mitzvah(2, prohibition, no_other_gods, always). -mitzvah(3, belief, unity_of_hashem, always). -mitzvah(4, positive, love_hashem, always). -mitzvah(5, positive, fear_hashem, always). -mitzvah(6, positive, sanctify_the_name, when(opportunity_arises)). -mitzvah(7, prohibition, not_profane_the_name, always). -mitzvah(8, prohibition, not_destroy_holy_things, always). -mitzvah(9, positive, hear_shema, when(morning_and_evening)). -mitzvah(10, positive, study_torah, always). +%% --- BELIEFS AND KNOWLEDGE OF GOD (1-10) --- +mitzvah(1, positive, know_hashem, always). +mitzvah(2, positive, unity_of_hashem, always). +mitzvah(3, positive, love_hashem, always). +mitzvah(4, positive, fear_hashem, always). +mitzvah(5, positive, pray_to_hashem, always). +mitzvah(6, positive, cleave_to_hashem, always). +mitzvah(7, positive, swear_by_his_name, when(oath_required)). +mitzvah(8, positive, walk_in_his_ways, always). +mitzvah(9, positive, sanctify_the_name, when(opportunity_arises)). +mitzvah(10, positive, read_shema, when(morning_and_evening)). -%% ============================================================ -%% SHABBAT — MANDATORY CESSATION -%% ============================================================ +%% --- TORAH STUDY AND TRANSMISSION (11-19) --- +mitzvah(11, positive, study_torah, always). +mitzvah(12, positive, teach_torah, always). +mitzvah(13, positive, bind_tefillin_head, when(weekday_morning)). +mitzvah(14, positive, bind_tefillin_arm, when(weekday_morning)). +mitzvah(15, positive, make_tzitzit, when(wearing_four_cornered_garment)). +mitzvah(16, positive, affix_mezuzah, when(dwelling_established)). +mitzvah(17, positive, assemble_people_hakhel, when(sukkot_after_shmitah)). +mitzvah(18, positive, write_sefer_torah, always). +mitzvah(19, positive, king_writes_second_torah, when(king_appointed)). -mitzvah(154, positive, rest_on_shabbat, when(seventh_day)). -mitzvah(155, prohibition, not_work_on_shabbat, when(seventh_day)). -mitzvah(156, positive, sanctify_shabbat, when(seventh_day)). +%% --- TEMPLE AND SANCTUARY (20-38) --- +mitzvah(20, positive, build_sanctuary, when(ability_exists)). +mitzvah(21, positive, revere_sanctuary, always). +mitzvah(22, positive, guard_sanctuary, always). +mitzvah(23, positive, levites_serve_sanctuary, when(temple_standing)). +mitzvah(24, positive, kohanim_wash_hands_feet, when(temple_service)). +mitzvah(25, positive, kindle_menorah, when(temple_standing)). +mitzvah(26, positive, kohanim_bless_people, always). +mitzvah(27, positive, showbread_on_table, when(temple_standing)). +mitzvah(28, positive, burn_incense, when(temple_standing)). +mitzvah(29, positive, maintain_eternal_fire, when(temple_standing)). +mitzvah(30, positive, remove_ashes_from_altar, when(temple_standing)). +mitzvah(31, positive, send_away_tamei_from_camp, when(temple_standing)). +mitzvah(32, positive, honor_kohanim, always). +mitzvah(33, positive, kohanim_wear_vestments, when(temple_service)). +mitzvah(34, positive, carry_aron_on_shoulders, when(transport_required)). +mitzvah(35, positive, anoint_with_shemen_hamishchah, when(consecration)). +mitzvah(36, positive, levites_serve_in_shifts, when(temple_standing)). +mitzvah(37, positive, kohanim_become_tamei_for_relatives, when(close_relative_dies)). +mitzvah(38, positive, kohen_gadol_marries_virgin, when(kohen_gadol_appointed)). -%% Festivals -mitzvah(159, positive, rest_on_yom_tov, when(festival)). -mitzvah(160, prohibition, not_work_on_yom_tov, when(festival)). -mitzvah(163, positive, rest_on_rosh_hashanah, when(tishrei_1)). -mitzvah(164, positive, fast_on_yom_kippur, when(tishrei_10)). +%% --- KORBANOT / OFFERINGS (39-88) --- +mitzvah(39, positive, bring_tamid_morning, when(temple_standing)). +mitzvah(40, positive, bring_tamid_afternoon, when(temple_standing)). +mitzvah(41, positive, kohen_gadol_minchah_daily, when(temple_standing)). +mitzvah(42, positive, bring_musaf_shabbat, when(shabbat_temple)). +mitzvah(43, positive, bring_musaf_rosh_chodesh, when(rosh_chodesh_temple)). +mitzvah(44, positive, bring_musaf_pesach, when(pesach_temple)). +mitzvah(45, positive, bring_omer_offering, when(sixteen_nisan_temple)). +mitzvah(46, positive, bring_musaf_shavuot, when(shavuot_temple)). +mitzvah(47, positive, bring_two_loaves_shavuot, when(shavuot_temple)). +mitzvah(48, positive, bring_musaf_rosh_hashanah, when(rosh_hashanah_temple)). +mitzvah(49, positive, bring_musaf_yom_kippur, when(yom_kippur_temple)). +mitzvah(50, positive, bring_yom_kippur_service, when(yom_kippur_temple)). +mitzvah(51, positive, bring_musaf_sukkot, when(sukkot_temple)). +mitzvah(52, positive, bring_musaf_shemini_atzeret, when(shemini_atzeret_temple)). +mitzvah(53, positive, bring_chagigah, when(three_festivals_temple)). +mitzvah(54, positive, appear_before_hashem_three_times, when(three_festivals_temple)). +mitzvah(55, positive, rejoice_on_festivals, when(festival)). +mitzvah(56, positive, slaughter_pesach_offering, when(fourteen_nisan)). +mitzvah(57, positive, eat_pesach_offering, when(pesach_night)). +mitzvah(58, positive, slaughter_second_pesach, when(fourteen_iyar)). +mitzvah(59, positive, eat_second_pesach_with_matzah, when(pesach_sheni_night)). +mitzvah(60, positive, blow_trumpets_over_offerings, when(temple_standing)). +mitzvah(61, positive, animals_from_eighth_day, when(offering_required)). +mitzvah(62, positive, offerings_unblemished, when(offering_required)). +mitzvah(63, positive, salt_every_offering, when(offering_required)). +mitzvah(64, positive, bring_olah, when(offering_required)). +mitzvah(65, positive, bring_chatat, when(unintentional_sin)). +mitzvah(66, positive, bring_asham, when(uncertain_transgression)). +mitzvah(67, positive, bring_asham_vadai, when(certain_transgression)). +mitzvah(68, positive, bring_shelamim, when(offering_required)). +mitzvah(69, positive, bring_minchah, when(offering_required)). +mitzvah(70, positive, court_brings_chatat_for_error, when(court_errs)). +mitzvah(71, positive, individual_brings_chatat_for_idolatry, when(individual_idolatry_error)). +mitzvah(72, positive, bring_asham_talui, when(uncertain_sin)). +mitzvah(73, positive, bring_asham_meilah, when(misuse_of_sacred)). +mitzvah(74, positive, confess_sins_with_offering, when(offering_required)). +mitzvah(75, positive, zav_brings_offering, when(zav_healed)). +mitzvah(76, positive, zavah_brings_offering, when(zavah_healed)). +mitzvah(77, positive, yoledet_brings_offering, when(after_birth)). +mitzvah(78, positive, metzora_brings_offering, when(metzora_healed)). +mitzvah(79, positive, tithe_animals, when(livestock_owned)). +mitzvah(80, positive, redeem_firstborn_son, when(firstborn_son_born)). +mitzvah(81, positive, redeem_firstborn_donkey, when(firstborn_donkey)). +mitzvah(82, positive, break_neck_unredeemed_donkey, when(unredeemed_donkey)). +mitzvah(83, positive, bring_all_offerings_to_temple, when(temple_standing)). +mitzvah(84, positive, bring_offerings_from_outside_to_temple, when(temple_standing)). +mitzvah(85, positive, redeem_blemished_consecrated_animals, when(blemished_consecration)). +mitzvah(86, positive, exchange_offering_is_holy, when(exchange_made)). +mitzvah(87, positive, kohanim_eat_remainder_of_minchah, when(temple_standing)). +mitzvah(88, positive, kohanim_eat_meat_of_chatat, when(temple_standing)). -%% Shmitah — the seventh year -mitzvah(134, positive, let_land_rest_in_shmitah, when(seventh_year)). -mitzvah(135, prohibition, not_work_land_in_shmitah, when(seventh_year)). -mitzvah(136, positive, release_debts_in_shmitah, when(seventh_year)). +%% --- CONSECRATION AND VOWS (89-95) --- +mitzvah(89, positive, burn_consecrated_that_became_tamei, when(became_tamei)). +mitzvah(90, positive, burn_notar, when(notar_remains)). +mitzvah(91, positive, nazirite_lets_hair_grow, when(nazirite_vow)). +mitzvah(92, positive, nazirite_shaves_at_completion, when(nazirite_completion)). +mitzvah(93, positive, fulfill_verbal_vow, always). +mitzvah(94, positive, annul_vow_per_rules, when(vow_annulment_conditions)). +mitzvah(95, positive, nazir_who_becomes_tamei_brings_offering, when(nazir_tamei)). -%% ============================================================ -%% THE THREE HALT CONDITIONS (Cardinal sins — yehareg v'al ya'avor) -%% ============================================================ - -%% Avodah Zarah — idolatry / misattributed authority -%% mitzvah(2) already declared in Beliefs section above -mitzvah(14, prohibition, not_make_idols, always). -mitzvah(15, prohibition, not_make_idols_for_others, always). -mitzvah(16, prohibition, not_worship_idols, always). -mitzvah(17, prohibition, not_bow_to_idols, always). - -%% Shfichut Damim — bloodshed / destruction of tzelem carrier -mitzvah(289, prohibition, not_murder, always). -mitzvah(290, prohibition, not_cause_death_of_innocent, always). -mitzvah(295, positive, save_the_pursued, when(pursuit_in_progress)). - -%% Gilui Arayot — forbidden relations / collapse of required distinctions -mitzvah(330, prohibition, not_commit_adultery, always). -mitzvah(353, prohibition, maintain_boundaries, always). - -%% ============================================================ -%% JUSTICE AND JUDGMENT (Sanhedrin-relevant) -%% ============================================================ - -mitzvah(175, positive, appoint_judges, always). -mitzvah(176, prohibition, not_judge_unjustly, always). -mitzvah(177, prohibition, not_favor_the_powerful, always). -mitzvah(178, prohibition, not_pervert_justice_for_poor, always). -mitzvah(179, positive, judge_righteously, always). -mitzvah(180, prohibition, not_accept_bribes, always). -mitzvah(181, positive, follow_the_majority, when(court_deliberation)). -mitzvah(182, prohibition, not_follow_majority_for_evil, when(court_deliberation)). - -%% Capital cases — relevant to Sanhedrin unanimous rejection rule -mitzvah(183, prohibition, not_convict_on_one_witness, when(capital_case)). -mitzvah(184, positive, investigate_thoroughly, when(capital_case)). - -%% ============================================================ -%% KORBANOT (Offerings — relevant to korban processor) -%% ============================================================ - -mitzvah(62, positive, bring_olah, when(offering_required)). -mitzvah(63, positive, bring_shelamim, when(offering_required)). -mitzvah(64, positive, bring_chatat, when(unintentional_sin)). -mitzvah(65, positive, bring_asham, when(uncertain_transgression)). -mitzvah(66, positive, bring_minchah, when(offering_required)). - -%% ============================================================ -%% TESTIMONY AND TRUTH (relevant to system integrity) -%% ============================================================ - -mitzvah(285, prohibition, not_bear_false_witness, always). -mitzvah(286, positive, testify_truthfully, when(knowledge_exists)). -mitzvah(287, prohibition, not_withhold_testimony, always). - -%% ============================================================ -%% SPEECH AND ATTRIBUTION -%% ============================================================ - -mitzvah(235, prohibition, not_take_name_in_vain, always). -mitzvah(236, prohibition, not_swear_falsely, always). - -%% ============================================================ -%% PROPERTY AND BOUNDARIES (relevant to manna/anti-hoarding) -%% ============================================================ - -mitzvah(243, prohibition, not_covet, always). -mitzvah(244, prohibition, not_desire_others_property, always). -mitzvah(247, prohibition, not_steal, always). -mitzvah(248, prohibition, not_move_boundary_markers, always). - -%% ============================================================ -%% BIKURIM AND TERUMAH (relevant to release protocol) -%% ============================================================ +%% --- RITUAL PURITY (96-113) --- +mitzvah(96, positive, anyone_who_touches_nevelah_is_tamei, always). +mitzvah(97, positive, eight_sheratzim_transmit_tumah, always). +mitzvah(98, positive, foods_become_tamei, always). +mitzvah(99, positive, niddah_is_temeiah, always). +mitzvah(100, positive, yoledet_is_temeiah, always). +mitzvah(101, positive, metzora_is_tamei, always). +mitzvah(102, positive, metzora_garment_is_tamei, always). +mitzvah(103, positive, metzora_house_is_tamei, always). +mitzvah(104, positive, zav_is_tamei, always). +mitzvah(105, positive, zavah_is_temeiah, always). +mitzvah(106, positive, corpse_is_tamei, always). +mitzvah(107, positive, parah_adumah_purifies, when(corpse_tumah)). +mitzvah(108, positive, immerse_in_mikveh, when(tumah_contracted)). +mitzvah(109, positive, metzora_purification_procedure, when(metzora_healed)). +mitzvah(110, positive, metzora_shaves_all_hair, when(metzora_purification)). +mitzvah(111, positive, metzora_identified_by_signs, always). +mitzvah(112, positive, sotah_procedure, when(sotah_suspected)). +mitzvah(113, positive, eglah_arufah_procedure, when(unknown_murder)). +%% --- AGRICULTURE AND GIFTS TO KOHANIM (114-145) --- +mitzvah(114, positive, separate_terumah_gedolah, when(produce_available)). +mitzvah(115, positive, separate_maaser_rishon, when(produce_available)). +mitzvah(116, positive, separate_maaser_sheni, when(produce_years_1_2_4_5)). +mitzvah(117, positive, levites_separate_terumat_maaser, when(maaser_received)). +mitzvah(118, positive, separate_maaser_ani, when(produce_years_3_6)). +mitzvah(119, positive, recite_vidui_maaserot, when(fourth_year_erev_pesach)). +mitzvah(120, positive, recite_mikra_bikurim, when(bringing_bikurim)). +mitzvah(121, positive, separate_challah, when(dough_kneaded)). +mitzvah(122, positive, let_land_rest_shmitah, when(seventh_year)). +mitzvah(123, positive, rest_land_yovel, when(fiftieth_year)). +mitzvah(124, positive, blow_shofar_yovel, when(yom_kippur_yovel)). mitzvah(125, positive, bring_bikurim, when(first_fruits_available)). mitzvah(126, positive, recite_bikurim_declaration, when(bringing_bikurim)). mitzvah(127, positive, separate_terumah, when(produce_available)). +mitzvah(128, positive, leave_peah, when(harvest)). +mitzvah(129, positive, leave_leket, when(harvest)). +mitzvah(130, positive, leave_forgotten_sheaf, when(harvest)). +mitzvah(131, positive, leave_peret_of_vineyard, when(grape_harvest)). +mitzvah(132, positive, leave_olelot, when(grape_harvest)). +mitzvah(133, positive, bring_fourth_year_fruit, when(fourth_year_planting)). +mitzvah(134, positive, let_shmitah_produce_be_free, when(seventh_year)). +mitzvah(135, positive, release_debts_shmitah, when(seventh_year)). +mitzvah(136, positive, count_omer_days, when(pesach_to_shavuot)). +mitzvah(137, positive, sanctify_yovel_fiftieth_year, when(fiftieth_year)). +mitzvah(138, positive, eat_matzah_pesach_night, when(pesach_night)). +mitzvah(139, positive, tell_exodus_story, when(pesach_night)). +mitzvah(140, positive, remove_chametz, when(fourteen_nisan)). +mitzvah(141, positive, rest_first_day_pesach, when(fifteen_nisan)). +mitzvah(142, positive, rest_seventh_day_pesach, when(twentyone_nisan)). +mitzvah(143, positive, rest_shavuot, when(six_sivan)). +mitzvah(144, positive, rest_rosh_hashanah, when(one_tishrei)). +mitzvah(145, positive, fast_yom_kippur, when(ten_tishrei)). + +%% --- SHABBAT AND FESTIVALS (146-171) --- +mitzvah(146, positive, rest_yom_kippur, when(ten_tishrei)). +mitzvah(147, positive, rest_first_day_sukkot, when(fifteen_tishrei)). +mitzvah(148, positive, rest_shemini_atzeret, when(twentytwo_tishrei)). +mitzvah(149, positive, dwell_in_sukkah, when(sukkot)). +mitzvah(150, positive, take_lulav, when(sukkot)). +mitzvah(151, positive, hear_shofar_rosh_hashanah, when(one_tishrei)). +mitzvah(152, positive, give_half_shekel, when(annually)). +mitzvah(153, positive, sanctify_new_month, when(new_moon_sighted)). +mitzvah(154, positive, rest_on_shabbat, when(seventh_day)). +mitzvah(155, positive, sanctify_shabbat, when(seventh_day)). +mitzvah(156, positive, destroy_chametz, when(fourteen_nisan)). +mitzvah(157, positive, give_shekel_for_communal_offerings, when(annually_temple)). +mitzvah(158, positive, count_seven_weeks, when(pesach_to_shavuot)). +mitzvah(159, positive, rest_on_yom_tov, when(festival)). +mitzvah(160, positive, eat_pesach_second_night_matzah, when(pesach_sheni)). +mitzvah(161, positive, circumcise_males, when(eighth_day)). +mitzvah(162, positive, slaughter_pesach_afternoon, when(fourteen_nisan)). +mitzvah(163, positive, rest_rosh_hashanah_second_day, when(two_tishrei)). +mitzvah(164, positive, dwell_sukkah_seven_days, when(sukkot)). + +%% --- JUSTICE AND COURTS (165-193) --- +mitzvah(165, positive, appoint_judges, always). +mitzvah(166, positive, treat_litigants_equally, when(court_deliberation)). +mitzvah(167, positive, testify_in_court, when(knowledge_exists)). +mitzvah(168, positive, investigate_witnesses, when(court_case)). +mitzvah(169, positive, judge_by_majority, when(court_deliberation)). +mitzvah(170, positive, execute_four_methods, when(capital_sentence)). +mitzvah(171, positive, hang_after_stoning, when(certain_offenses)). +mitzvah(172, positive, bury_executed_same_day, when(execution)). +mitzvah(173, positive, pursue_justice, always). +mitzvah(174, positive, follow_beit_din_hagadol, always). +mitzvah(175, positive, follow_majority_in_court, when(court_deliberation)). +mitzvah(176, positive, appoint_king, when(king_needed)). +mitzvah(177, positive, obey_kohen_gadol, when(temple_standing)). +mitzvah(178, positive, judge_righteously, always). +mitzvah(179, positive, investigate_thoroughly, when(capital_case)). + +%% --- MONETARY LAW AND DAMAGES (180-207) --- +mitzvah(180, positive, return_stolen_property, when(theft_occurred)). +mitzvah(181, positive, give_tzedakah, always). +mitzvah(182, positive, give_gifts_to_kohanim, when(applicable)). +mitzvah(183, positive, lend_to_poor, when(poor_person_needs)). +mitzvah(184, positive, lend_to_gentile_with_interest, when(loan_to_gentile)). +mitzvah(185, positive, return_pledge_when_needed, when(pledge_held)). +mitzvah(186, positive, pay_wages_on_time, always). +mitzvah(187, positive, allow_worker_to_eat, when(working_with_food)). +mitzvah(188, positive, help_unload_animal, when(animal_struggling)). +mitzvah(189, positive, help_load_animal, when(animal_needs_loading)). +mitzvah(190, positive, return_lost_property, when(found_property)). +mitzvah(191, positive, rebuke_sinner, always). +mitzvah(192, positive, love_fellow_jew, always). +mitzvah(193, positive, love_convert, always). + +%% --- WEIGHTS, MEASURES, AND COMMERCE (194-209) --- +mitzvah(194, positive, have_accurate_weights, always). +mitzvah(195, positive, honor_the_wise, always). +mitzvah(196, positive, honor_parents, always). +mitzvah(197, positive, fear_parents, always). +mitzvah(198, positive, be_fruitful_multiply, always). +mitzvah(199, positive, marriage_by_kiddushin, when(marriage)). +mitzvah(200, positive, groom_rejoices_with_bride_one_year, when(first_year_marriage)). +mitzvah(201, positive, circumcise_son, when(eighth_day)). +mitzvah(202, positive, yibum_levirate_marriage, when(brother_dies_childless)). +mitzvah(203, positive, chalitzah, when(yibum_refused)). +mitzvah(204, positive, rapist_marries_victim, when(rape_of_unmarried)). +mitzvah(205, positive, motzi_shem_ra_stays_married, when(false_accusation)). +mitzvah(206, positive, beautiful_captive_procedure, when(war_captive)). +mitzvah(207, positive, divorce_by_get, when(divorce)). + +%% --- SLAVES AND SERVANTS (208-216) --- +mitzvah(208, positive, hebrew_slave_laws, when(hebrew_slave)). +mitzvah(209, positive, betroth_hebrew_maidservant, when(hebrew_maidservant)). +mitzvah(210, positive, redeem_hebrew_maidservant, when(hebrew_maidservant)). +mitzvah(211, positive, canaanite_slave_forever, when(canaanite_slave)). +mitzvah(212, positive, provide_for_freed_slave, when(slave_freed)). +mitzvah(213, positive, eved_ivri_goes_free_six, when(six_years_served)). +mitzvah(214, positive, eved_nirtza_freed_yovel, when(yovel_year)). +mitzvah(215, positive, freed_slave_provision, when(slave_released)). +mitzvah(216, positive, treat_hired_worker_justly, always). + +%% --- WAR AND MONARCHY (217-231) --- +mitzvah(217, positive, anoint_king_from_israel, when(king_appointed)). +mitzvah(218, positive, obey_king, when(king_rules)). +mitzvah(219, positive, king_writes_torah_scroll, when(king_appointed)). +mitzvah(220, positive, kohen_anointed_for_war_speaks, when(going_to_war)). +mitzvah(221, positive, prepare_camp_properly, when(war_camp)). +mitzvah(222, positive, prepare_place_outside_camp, when(war_camp)). +mitzvah(223, positive, prepare_stake_for_covering, when(war_camp)). +mitzvah(224, positive, destroy_seven_nations, when(entering_land)). +mitzvah(225, positive, destroy_amalek, when(opportunity_arises)). +mitzvah(226, positive, remember_amalek, always). +mitzvah(227, positive, offer_peace_before_war, when(going_to_war)). +mitzvah(228, positive, kohen_speaks_to_army, when(going_to_war)). +mitzvah(229, positive, send_home_fearful, when(going_to_war)). +mitzvah(230, positive, besiege_city_correctly, when(siege)). +mitzvah(231, positive, laws_of_ir_hanidachat, when(city_turned_idolatrous)). + +%% --- FAMILY AND PURITY (232-248) --- +mitzvah(232, positive, laws_of_tzaraat_in_person, always). +mitzvah(233, positive, laws_of_tzaraat_in_garment, always). +mitzvah(234, positive, laws_of_tzaraat_in_house, always). +mitzvah(235, positive, niddah_counts_seven_clean_days, when(niddah)). +mitzvah(236, positive, zavah_counts_seven_clean_days, when(zavah)). +mitzvah(237, positive, zav_counts_seven_clean_days, when(zav)). +mitzvah(238, positive, immerse_all_keilim_in_mikveh, when(new_vessels)). +mitzvah(239, positive, break_earthenware_that_absorbed_tumah, when(tumah_absorbed)). +mitzvah(240, positive, eglah_arufah_for_unsolved_murder, when(murdered_body_found)). +mitzvah(241, positive, build_cities_of_refuge, when(in_land)). +mitzvah(242, positive, give_levite_cities, when(in_land)). +mitzvah(243, positive, build_maakeh_fence_on_roof, always). +mitzvah(244, positive, remove_stumbling_blocks, always). +mitzvah(245, positive, send_mother_bird_away, when(birds_nest_found)). +mitzvah(246, positive, cover_blood_of_slaughtered_bird, when(slaughter)). +mitzvah(247, positive, shiluach_haken, when(birds_nest_found)). +mitzvah(248, positive, guard_ones_life, always). + +%% ============================================================ +%% 365 PROHIBITIONS (Mitzvot Lo Ta'aseh) +%% ============================================================ +%% Mapped to IDs 249-613 (249 = prohibition 1, 613 = prohibition 365) + +%% --- IDOLATRY AND FALSE WORSHIP (249-300) --- +mitzvah(249, prohibition, no_other_gods, always). +mitzvah(250, prohibition, not_make_idols, always). +mitzvah(251, prohibition, not_make_idols_for_others, always). +mitzvah(252, prohibition, not_make_figured_stones, always). +mitzvah(253, prohibition, not_plant_asheirah, always). +mitzvah(254, prohibition, not_worship_idols_their_way, always). +mitzvah(255, prohibition, not_bow_to_idols, always). +mitzvah(256, prohibition, not_worship_molech, always). +mitzvah(257, prohibition, not_practice_ov, always). +mitzvah(258, prohibition, not_practice_yidoni, always). +mitzvah(259, prohibition, not_turn_to_idols, always). +mitzvah(260, prohibition, not_erect_pillar, always). +mitzvah(261, prohibition, not_make_figured_stones_to_bow, always). +mitzvah(262, prohibition, not_make_graven_image, always). +mitzvah(263, prohibition, not_prophesy_in_idol_name, always). +mitzvah(264, prohibition, not_listen_to_false_prophet, always). +mitzvah(265, prohibition, not_entice_to_idolatry, always). +mitzvah(266, prohibition, not_love_enticer, always). +mitzvah(267, prohibition, not_relax_guard_against_enticer, always). +mitzvah(268, prohibition, not_save_enticer, always). +mitzvah(269, prohibition, not_plead_for_enticer, always). +mitzvah(270, prohibition, not_refrain_from_testimony_against_enticer, always). +mitzvah(271, prohibition, not_benefit_from_ir_hanidachat, always). +mitzvah(272, prohibition, not_rebuild_ir_hanidachat, always). +mitzvah(273, prohibition, not_benefit_from_idol_offerings, always). +mitzvah(274, prohibition, not_prophesy_falsely, always). +mitzvah(275, prohibition, not_fear_false_prophet, always). +mitzvah(276, prohibition, not_swear_by_idols, always). +mitzvah(277, prohibition, not_invite_idol_worship, always). +mitzvah(278, prohibition, not_practice_divination, always). +mitzvah(279, prohibition, not_practice_soothsaying, always). +mitzvah(280, prohibition, not_practice_enchanting, always). +mitzvah(281, prohibition, not_practice_sorcery, always). +mitzvah(282, prohibition, not_practice_charming, always). +mitzvah(283, prohibition, not_consult_ov, always). +mitzvah(284, prohibition, not_consult_yidoni, always). +mitzvah(285, prohibition, not_practice_necromancy, always). +mitzvah(286, prohibition, not_cross_dress_woman_to_man, always). +mitzvah(287, prohibition, not_cross_dress_man_to_woman, always). +mitzvah(288, prohibition, not_tattoo, always). +mitzvah(289, prohibition, not_wear_shaatnez, always). +mitzvah(290, prohibition, not_shave_temples, always). +mitzvah(291, prohibition, not_destroy_beard_edges, always). +mitzvah(292, prohibition, not_cut_for_dead, always). +mitzvah(293, prohibition, not_settle_in_egypt, always). +mitzvah(294, prohibition, not_follow_heart_and_eyes, always). +mitzvah(295, prohibition, not_make_covenant_with_seven_nations, always). +mitzvah(296, prohibition, not_show_mercy_to_idolaters, always). +mitzvah(297, prohibition, not_allow_idolaters_in_land, always). +mitzvah(298, prohibition, not_intermarry_with_seven_nations, always). +mitzvah(299, prohibition, not_intermarry_male_moabite, always). +mitzvah(300, prohibition, not_make_peace_with_ammon_moab, always). + +%% --- PROHIBITIONS RELATING TO HASHEM AND TORAH (301-320) --- +mitzvah(301, prohibition, not_destroy_ammonite_edomite_third_gen, always). +mitzvah(302, prohibition, not_reject_egyptian_convert_third_gen, always). +mitzvah(303, prohibition, not_offer_peace_to_ammon_moab, always). +mitzvah(304, prohibition, not_destroy_fruit_trees_in_siege, always). +mitzvah(305, prohibition, not_fear_enemy_in_battle, always). +mitzvah(306, prohibition, not_forget_amalek, always). +mitzvah(307, prohibition, not_blaspheme_hashem, always). +mitzvah(308, prohibition, not_break_oath, always). +mitzvah(309, prohibition, not_take_name_in_vain, always). +mitzvah(310, prohibition, not_profane_the_name, always). +mitzvah(311, prohibition, not_test_hashem, always). +mitzvah(312, prohibition, not_destroy_holy_things, always). +mitzvah(313, prohibition, not_cease_guarding_temple, always). +mitzvah(314, prohibition, kohen_gadol_not_enter_kodesh_always, when(temple_standing)). +mitzvah(315, prohibition, kohen_with_blemish_not_enter, when(temple_standing)). +mitzvah(316, prohibition, kohen_with_blemish_not_serve, when(temple_standing)). +mitzvah(317, prohibition, kohen_with_temporary_blemish_not_serve, when(temple_standing)). +mitzvah(318, prohibition, levites_not_do_kohen_work, when(temple_standing)). +mitzvah(319, prohibition, kohanim_not_do_levite_work, when(temple_standing)). +mitzvah(320, prohibition, not_enter_sanctuary_intoxicated, when(temple_standing)). + +%% --- OFFERINGS AND SACRED THINGS (321-370) --- +mitzvah(321, prohibition, zar_not_serve_in_temple, when(temple_standing)). +mitzvah(322, prohibition, tamei_kohen_not_serve, when(temple_standing)). +mitzvah(323, prohibition, kohen_who_immersed_wait_sunset, when(temple_standing)). +mitzvah(324, prohibition, tamei_not_enter_temple, when(temple_standing)). +mitzvah(325, prohibition, tamei_not_enter_temple_mount, when(temple_standing)). +mitzvah(326, prohibition, not_build_altar_of_hewn_stone, when(temple_standing)). +mitzvah(327, prohibition, not_ascend_altar_by_steps, when(temple_standing)). +mitzvah(328, prohibition, not_extinguish_altar_fire, when(temple_standing)). +mitzvah(329, prohibition, not_burn_incense_on_golden_altar_except, when(temple_standing)). +mitzvah(330, prohibition, not_make_oil_like_anointing_oil, always). +mitzvah(331, prohibition, not_make_incense_like_ketoret, always). +mitzvah(332, prohibition, not_anoint_with_shemen_hamishchah, always). +mitzvah(333, prohibition, not_remove_staves_from_aron, always). +mitzvah(334, prohibition, not_remove_choshen_from_ephod, always). +mitzvah(335, prohibition, not_tear_me_il, always). +mitzvah(336, prohibition, not_offer_blemished_animal, when(offering)). +mitzvah(337, prohibition, not_slaughter_blemished_animal, when(offering)). +mitzvah(338, prohibition, not_sprinkle_blood_of_blemished, when(offering)). +mitzvah(339, prohibition, not_burn_fats_of_blemished, when(offering)). +mitzvah(340, prohibition, not_offer_temporarily_blemished, when(offering)). +mitzvah(341, prohibition, not_offer_blemished_from_gentile, when(offering)). +mitzvah(342, prohibition, not_make_blemish_in_consecrated, when(offering)). +mitzvah(343, prohibition, not_offer_leaven_or_honey, when(offering)). +mitzvah(344, prohibition, not_offer_without_salt, when(offering)). +mitzvah(345, prohibition, not_offer_etnan_or_mechir, when(offering)). +mitzvah(346, prohibition, not_slaughter_animal_and_young_same_day, always). +mitzvah(347, prohibition, not_put_oil_on_chatat_minchah, when(offering)). +mitzvah(348, prohibition, not_put_levonah_on_chatat_minchah, when(offering)). +mitzvah(349, prohibition, not_put_oil_on_sotah_minchah, when(offering)). +mitzvah(350, prohibition, not_put_levonah_on_sotah_minchah, when(offering)). +mitzvah(351, prohibition, not_exchange_consecrated_animal, when(offering)). +mitzvah(352, prohibition, not_change_designation_of_offering, when(offering)). +mitzvah(353, prohibition, not_redeem_firstborn_animal, when(firstborn)). +mitzvah(354, prohibition, not_sell_maaser_behemah, when(animal_tithe)). +mitzvah(355, prohibition, not_sell_cherem_field, always). +mitzvah(356, prohibition, not_sell_cherem_field_of_levites, always). +mitzvah(357, prohibition, not_cut_head_of_eglah_arufah_nape, when(eglah_arufah)). +mitzvah(358, prohibition, not_sow_or_prune_ir_hanidachat, always). +mitzvah(359, prohibition, not_eat_offerings_of_lesser_sanctity_before_blood, when(offering)). +mitzvah(360, prohibition, kohen_not_eat_bikurim_outside_jerusalem, when(temple)). +mitzvah(361, prohibition, not_eat_chatat_outside_temple, when(temple)). +mitzvah(362, prohibition, not_eat_olah_meat, when(offering)). +mitzvah(363, prohibition, not_eat_kodshei_kalim_before_blood, when(offering)). +mitzvah(364, prohibition, zar_not_eat_terumah, always). +mitzvah(365, prohibition, kohen_tenant_not_eat_terumah, always). +mitzvah(366, prohibition, uncircumcised_not_eat_terumah, always). +mitzvah(367, prohibition, tamei_kohen_not_eat_terumah, always). +mitzvah(368, prohibition, chalalah_not_eat_terumah, always). +mitzvah(369, prohibition, not_eat_tevel, always). +mitzvah(370, prohibition, not_eat_maaser_sheni_in_tumah, always). + +%% --- FOOD AND KASHRUT (371-420) --- +mitzvah(371, prohibition, not_eat_maaser_sheni_while_onen, always). +mitzvah(372, prohibition, not_spend_maaser_sheni_on_dead, always). +mitzvah(373, prohibition, not_eat_fourth_year_fruit_unredeemed, always). +mitzvah(374, prohibition, not_eat_chametz_on_pesach, when(pesach)). +mitzvah(375, prohibition, not_eat_chametz_mixture_on_pesach, when(pesach)). +mitzvah(376, prohibition, not_see_chametz_in_possession, when(pesach)). +mitzvah(377, prohibition, not_find_chametz_in_possession, when(pesach)). +mitzvah(378, prohibition, nazirite_not_drink_wine, when(nazirite_vow)). +mitzvah(379, prohibition, nazirite_not_eat_grapes, when(nazirite_vow)). +mitzvah(380, prohibition, nazirite_not_eat_raisins, when(nazirite_vow)). +mitzvah(381, prohibition, nazirite_not_eat_grape_seeds, when(nazirite_vow)). +mitzvah(382, prohibition, nazirite_not_eat_grape_skins, when(nazirite_vow)). +mitzvah(383, prohibition, nazirite_not_become_tamei, when(nazirite_vow)). +mitzvah(384, prohibition, nazirite_not_enter_tent_of_dead, when(nazirite_vow)). +mitzvah(385, prohibition, nazirite_not_shave, when(nazirite_vow)). +mitzvah(386, prohibition, not_harvest_entire_field, when(harvest)). +mitzvah(387, prohibition, not_gather_gleanings, when(harvest)). +mitzvah(388, prohibition, not_harvest_unformed_grape_clusters, when(grape_harvest)). +mitzvah(389, prohibition, not_gather_fallen_grapes, when(grape_harvest)). +mitzvah(390, prohibition, not_return_for_forgotten_sheaf, when(harvest)). +mitzvah(391, prohibition, not_sow_mixed_seeds, always). +mitzvah(392, prohibition, not_sow_grain_in_vineyard, always). +mitzvah(393, prohibition, not_crossbreed_animals, always). +mitzvah(394, prohibition, not_plow_with_ox_and_donkey, always). +mitzvah(395, prohibition, not_muzzle_working_animal, always). +mitzvah(396, prohibition, not_work_land_in_shmitah, when(seventh_year)). +mitzvah(397, prohibition, not_prune_trees_in_shmitah, when(seventh_year)). +mitzvah(398, prohibition, not_harvest_shmitah_as_normal, when(seventh_year)). +mitzvah(399, prohibition, not_harvest_grapes_in_shmitah_as_normal, when(seventh_year)). +mitzvah(400, prohibition, not_work_land_in_yovel, when(fiftieth_year)). +mitzvah(401, prohibition, not_harvest_yovel_as_normal, when(fiftieth_year)). +mitzvah(402, prohibition, not_harvest_grapes_yovel_as_normal, when(fiftieth_year)). +mitzvah(403, prohibition, not_sell_land_permanently, always). +mitzvah(404, prohibition, not_change_levite_city_fields, always). +mitzvah(405, prohibition, not_forsake_levites, always). +mitzvah(406, prohibition, not_demand_debt_in_shmitah, when(seventh_year)). +mitzvah(407, prohibition, not_refrain_from_lending_before_shmitah, always). +mitzvah(408, prohibition, not_withhold_charity, always). +mitzvah(409, prohibition, not_send_hebrew_slave_empty, when(slave_freed)). +mitzvah(410, prohibition, not_charge_interest_to_jew, always). +mitzvah(411, prohibition, not_facilitate_interest_loan, always). +mitzvah(412, prohibition, not_oppress_debtor, always). +mitzvah(413, prohibition, not_take_pledge_by_force, always). +mitzvah(414, prohibition, not_keep_pledge_from_poor_overnight, always). +mitzvah(415, prohibition, not_take_pledge_from_widow, always). +mitzvah(416, prohibition, not_take_food_utensils_as_pledge, always). +mitzvah(417, prohibition, not_kidnap, always). +mitzvah(418, prohibition, not_steal, always). +mitzvah(419, prohibition, not_rob, always). +mitzvah(420, prohibition, not_move_boundary_marker, always). + +%% --- JUSTICE AND TESTIMONY (421-460) --- +mitzvah(421, prohibition, not_deny_debt, always). +mitzvah(422, prohibition, not_swear_falsely_about_property, always). +mitzvah(423, prohibition, not_wrong_in_commerce, always). +mitzvah(424, prohibition, not_wrong_with_words, always). +mitzvah(425, prohibition, not_wrong_convert_in_commerce, always). +mitzvah(426, prohibition, not_wrong_convert_with_words, always). +mitzvah(427, prohibition, not_return_slave_to_master, always). +mitzvah(428, prohibition, not_oppress_escaped_slave, always). +mitzvah(429, prohibition, not_afflict_widow_orphan, always). +mitzvah(430, prohibition, not_work_hebrew_slave_harshly, always). +mitzvah(431, prohibition, not_sell_hebrew_slave_publicly, always). +mitzvah(432, prohibition, not_work_hebrew_slave_degradingly, always). +mitzvah(433, prohibition, not_sell_captured_woman, always). +mitzvah(434, prohibition, not_enslave_captured_woman, always). +mitzvah(435, prohibition, not_delay_wages, always). +mitzvah(436, prohibition, not_take_security_from_debtor_employer, always). +mitzvah(437, prohibition, not_have_false_weights, always). +mitzvah(438, prohibition, not_have_false_measures, always). +mitzvah(439, prohibition, judge_not_be_unjust, always). +mitzvah(440, prohibition, judge_not_accept_bribe, always). +mitzvah(441, prohibition, judge_not_favor_powerful, always). +mitzvah(442, prohibition, judge_not_pervert_poor_case, always). +mitzvah(443, prohibition, judge_not_pervert_case_of_sinner, always). +mitzvah(444, prohibition, judge_not_show_pity_to_poor_in_judgment, always). +mitzvah(445, prohibition, not_pervert_convert_orphan_judgment, always). +mitzvah(446, prohibition, not_hear_one_side_without_other, always). +mitzvah(447, prohibition, not_convict_on_one_witness, always). +mitzvah(448, prohibition, not_appoint_unqualified_judge, always). +mitzvah(449, prohibition, not_bear_false_witness, always). +mitzvah(450, prohibition, not_follow_majority_for_evil, when(court_deliberation)). +mitzvah(451, prohibition, judge_not_follow_senior_in_capital, when(capital_case)). +mitzvah(452, prohibition, not_decide_capital_by_one_vote, when(capital_case)). +mitzvah(453, prohibition, accuser_not_become_advocate, when(capital_case)). +mitzvah(454, prohibition, not_punish_one_forced, always). +mitzvah(455, prohibition, not_punish_based_on_circumstantial_evidence, always). +mitzvah(456, prohibition, not_accept_ransom_for_murderer, always). +mitzvah(457, prohibition, not_accept_ransom_for_accidental_killer, always). +mitzvah(458, prohibition, not_testify_in_own_cause, always). +mitzvah(459, prohibition, not_curse_judge, always). +mitzvah(460, prohibition, not_curse_nasi, always). + +%% --- MURDER, INJURY AND HARM (461-490) --- +mitzvah(461, prohibition, not_murder, always). +mitzvah(462, prohibition, not_strike_parent, always). +mitzvah(463, prohibition, not_curse_parent, always). +mitzvah(464, prohibition, not_curse_any_jew, always). +mitzvah(465, prohibition, not_put_stumbling_block_before_blind, always). +mitzvah(466, prohibition, not_strike_fellow_jew, always). +mitzvah(467, prohibition, not_cause_death_of_innocent, always). +mitzvah(468, prohibition, not_stand_idly_by_blood, always). +mitzvah(469, prohibition, not_leave_dangerous_hazard, always). +mitzvah(470, prohibition, not_mislead_with_bad_advice, always). +mitzvah(471, prohibition, not_punish_more_than_prescribed, always). +mitzvah(472, prohibition, not_gossip, always). +mitzvah(473, prohibition, not_hate_in_heart, always). +mitzvah(474, prohibition, not_shame_fellow_publicly, always). +mitzvah(475, prohibition, not_take_revenge, always). +mitzvah(476, prohibition, not_bear_grudge, always). +mitzvah(477, prohibition, not_take_mother_bird_with_young, when(birds_nest)). +mitzvah(478, prohibition, not_cause_unnecessary_suffering_to_animals, always). +mitzvah(479, prohibition, not_leave_animal_fallen_under_load, always). +mitzvah(480, prohibition, not_castrate_any_creature, always). +mitzvah(481, prohibition, not_offer_damaged_animal, when(offering)). +mitzvah(482, prohibition, not_damage_fruit_trees_in_war, when(siege)). +mitzvah(483, prohibition, metzora_not_shave_signs, always). +mitzvah(484, prohibition, not_pull_out_tzaraat_signs, always). +mitzvah(485, prohibition, not_plow_valley_of_eglah_arufah, when(eglah_arufah)). +mitzvah(486, prohibition, killer_not_leave_refuge_before_kohen_gadol_dies, when(in_refuge)). +mitzvah(487, prohibition, avenger_not_kill_accidental_slayer_in_refuge, always). +mitzvah(488, prohibition, not_withhold_testimony, always). +mitzvah(489, prohibition, not_fail_to_save_pursued, when(pursuit)). +mitzvah(490, prohibition, not_destroy_anything_needlessly, always). + +%% --- FORBIDDEN RELATIONS (491-550) --- +mitzvah(491, prohibition, not_commit_adultery, always). +mitzvah(492, prohibition, not_have_relations_with_mother, always). +mitzvah(493, prohibition, not_have_relations_with_fathers_wife, always). +mitzvah(494, prohibition, not_have_relations_with_sister, always). +mitzvah(495, prohibition, not_have_relations_with_half_sister_mother, always). +mitzvah(496, prohibition, not_have_relations_with_sons_daughter, always). +mitzvah(497, prohibition, not_have_relations_with_daughter, always). +mitzvah(498, prohibition, not_have_relations_with_daughters_daughter, always). +mitzvah(499, prohibition, not_marry_woman_and_daughter, always). +mitzvah(500, prohibition, not_marry_woman_and_sons_daughter, always). +mitzvah(501, prohibition, not_marry_woman_and_daughters_daughter, always). +mitzvah(502, prohibition, not_have_relations_with_fathers_sister, always). +mitzvah(503, prohibition, not_have_relations_with_mothers_sister, always). +mitzvah(504, prohibition, not_have_relations_with_fathers_brothers_wife, always). +mitzvah(505, prohibition, not_have_relations_with_sons_wife, always). +mitzvah(506, prohibition, not_have_relations_with_brothers_wife, always). +mitzvah(507, prohibition, not_have_relations_with_wifes_sister, always). +mitzvah(508, prohibition, not_have_relations_with_animal, always). +mitzvah(509, prohibition, woman_not_have_relations_with_animal, always). +mitzvah(510, prohibition, not_have_homosexual_relations, always). +mitzvah(511, prohibition, not_have_relations_with_fathers_brother, always). +mitzvah(512, prohibition, not_have_relations_with_married_woman, always). +mitzvah(513, prohibition, not_have_relations_with_niddah, always). +mitzvah(514, prohibition, not_intermarry, always). +mitzvah(515, prohibition, ammonite_male_not_marry_into_congregation, always). +mitzvah(516, prohibition, mamzer_not_marry_into_congregation, always). +mitzvah(517, prohibition, eunuch_not_marry_into_congregation, always). +mitzvah(518, prohibition, not_castrate_man, always). +mitzvah(519, prohibition, kohen_gadol_not_marry_widow, always). +mitzvah(520, prohibition, kohen_gadol_not_have_relations_with_widow, always). +mitzvah(521, prohibition, kohen_not_marry_divorcee, always). +mitzvah(522, prohibition, kohen_not_marry_zonah, always). +mitzvah(523, prohibition, kohen_not_marry_chalalah, always). +mitzvah(524, prohibition, not_approach_arayot, always). +mitzvah(525, prohibition, not_have_relations_outside_marriage, always). +mitzvah(526, prohibition, not_remarry_divorced_wife_after_remarriage, always). +mitzvah(527, prohibition, childless_brothers_wife_not_marry_outside, when(yibum_applies)). +mitzvah(528, prohibition, rapist_not_divorce_victim, when(rape_case)). +mitzvah(529, prohibition, motzi_shem_ra_not_divorce, when(false_accusation)). +mitzvah(530, prohibition, seris_not_marry_jewess, always). +mitzvah(531, prohibition, not_have_relations_with_animal_female, always). +mitzvah(532, prohibition, maintain_boundaries, always). +mitzvah(533, prohibition, kohen_gadol_not_marry_non_virgin, always). +mitzvah(534, prohibition, kohen_not_become_tamei_except_relatives, always). +mitzvah(535, prohibition, kohen_gadol_not_become_tamei_at_all, always). +mitzvah(536, prohibition, kohen_gadol_not_be_under_same_roof_as_dead, always). +mitzvah(537, prohibition, levite_not_abandon_post, when(temple_standing)). +mitzvah(538, prohibition, not_prophesy_what_not_heard, always). +mitzvah(539, prohibition, not_refrain_from_killing_false_prophet, always). +mitzvah(540, prohibition, not_fear_killing_false_prophet, always). +mitzvah(541, prohibition, not_swear_falsely, always). +mitzvah(542, prohibition, not_delay_vow_fulfillment, always). +mitzvah(543, prohibition, not_break_oath, always). +mitzvah(544, prohibition, not_vow_in_anger, always). +mitzvah(545, prohibition, not_let_kohen_become_tamei_unnecessarily, always). +mitzvah(546, prohibition, not_offer_anything_on_private_altar, when(temple_standing)). +mitzvah(547, prohibition, not_slaughter_offering_outside_temple, when(temple_standing)). +mitzvah(548, prohibition, not_eat_meat_of_offering_with_blemish, when(offering)). +mitzvah(549, prohibition, not_eat_notar, when(offering)). +mitzvah(550, prohibition, not_eat_piggul, when(offering)). + +%% --- FOOD PROHIBITIONS (551-600) --- +mitzvah(551, prohibition, not_eat_non_kosher_animal, always). +mitzvah(552, prohibition, not_eat_non_kosher_fish, always). +mitzvah(553, prohibition, not_eat_non_kosher_bird, always). +mitzvah(554, prohibition, not_eat_flying_insect, always). +mitzvah(555, prohibition, not_eat_ground_swarmer, always). +mitzvah(556, prohibition, not_eat_worm_from_fruit_once_emerged, always). +mitzvah(557, prohibition, not_eat_water_swarmer, always). +mitzvah(558, prohibition, not_eat_nevelah, always). +mitzvah(559, prohibition, not_eat_treifah, always). +mitzvah(560, prohibition, not_eat_limb_from_living, always). +mitzvah(561, prohibition, not_eat_blood, always). +mitzvah(562, prohibition, not_eat_certain_fats, always). +mitzvah(563, prohibition, not_eat_gid_hanasheh, always). +mitzvah(564, prohibition, not_eat_meat_and_milk, always). +mitzvah(565, prohibition, not_cook_meat_and_milk, always). +mitzvah(566, prohibition, not_eat_bread_from_new_grain_before_omer, when(before_omer)). +mitzvah(567, prohibition, not_eat_roasted_from_new_grain_before_omer, when(before_omer)). +mitzvah(568, prohibition, not_eat_fresh_from_new_grain_before_omer, when(before_omer)). +mitzvah(569, prohibition, not_eat_orlah_fruit, when(first_three_years)). +mitzvah(570, prohibition, not_eat_kilei_hakerem, always). +mitzvah(571, prohibition, not_drink_wine_of_libation, always). +mitzvah(572, prohibition, not_eat_or_drink_gluttonously, always). +mitzvah(573, prohibition, not_eat_on_yom_kippur, when(yom_kippur)). +mitzvah(574, prohibition, not_eat_chametz_during_pesach, when(pesach)). +mitzvah(575, prohibition, not_eat_chametz_mixture_pesach, when(pesach)). +mitzvah(576, prohibition, not_eat_chametz_after_midday_14_nisan, when(fourteen_nisan)). +mitzvah(577, prohibition, not_see_chametz, when(pesach)). +mitzvah(578, prohibition, not_find_chametz, when(pesach)). +mitzvah(579, prohibition, nazirite_not_eat_grape_product, when(nazirite)). +mitzvah(580, prohibition, nazirite_not_eat_grapes, when(nazirite)). +mitzvah(581, prohibition, nazirite_not_eat_raisins, when(nazirite)). +mitzvah(582, prohibition, nazirite_not_eat_seeds, when(nazirite)). +mitzvah(583, prohibition, nazirite_not_eat_skins, when(nazirite)). +mitzvah(584, prohibition, nazirite_not_drink_wine, when(nazirite)). +mitzvah(585, prohibition, nazirite_not_cut_hair, when(nazirite)). +mitzvah(586, prohibition, nazirite_not_become_tamei, when(nazirite)). +mitzvah(587, prohibition, not_eat_second_tithe_improperly, always). +mitzvah(588, prohibition, kohen_not_eat_first_fruits_outside_jerusalem, when(temple)). +mitzvah(589, prohibition, not_eat_unredeemed_second_tithe, always). +mitzvah(590, prohibition, not_eat_first_tithe_without_terumah_separated, always). +mitzvah(591, prohibition, not_eat_terumah_while_tamei, always). +mitzvah(592, prohibition, non_kohen_not_eat_terumah, always). +mitzvah(593, prohibition, kohen_tenant_not_eat_terumah, always). +mitzvah(594, prohibition, uncircumcised_kohen_not_eat_terumah, always). +mitzvah(595, prohibition, not_eat_tamei_terumah, always). +mitzvah(596, prohibition, not_eat_tevel, always). +mitzvah(597, prohibition, not_eat_second_tithe_while_tamei, always). +mitzvah(598, prohibition, not_eat_second_tithe_as_onen, always). +mitzvah(599, prohibition, not_spend_second_tithe_redemption_on_dead, always). +mitzvah(600, prohibition, not_eat_pesach_offering_raw, when(pesach)). + +%% --- REMAINING PROHIBITIONS (601-613) --- +mitzvah(601, prohibition, not_take_pesach_outside_group, when(pesach)). +mitzvah(602, prohibition, not_break_bone_of_pesach, when(pesach)). +mitzvah(603, prohibition, uncircumcised_not_eat_pesach, when(pesach)). +mitzvah(604, prohibition, apostate_not_eat_pesach, when(pesach)). +mitzvah(605, prohibition, gentile_not_eat_pesach, when(pesach)). +mitzvah(606, prohibition, not_leave_pesach_to_morning, when(pesach)). +mitzvah(607, prohibition, not_leave_festival_offering_to_third_day, when(festival)). +mitzvah(608, prohibition, not_leave_second_pesach_to_morning, when(pesach_sheni)). +mitzvah(609, prohibition, not_leave_todah_to_morning, when(offering)). +mitzvah(610, prohibition, not_break_bone_of_second_pesach, when(pesach_sheni)). +mitzvah(611, prohibition, not_eat_kohen_chatat_burned_inside, when(offering)). +mitzvah(612, prohibition, not_eat_disqualified_offering, when(offering)). +mitzvah(613, prohibition, not_eat_sanctified_that_became_tamei, when(offering)). %% ============================================================ %% SOURCE REFERENCES %% ============================================================ +%% Key mitzvot grounded in Torah verses -%% mitzvah_source(ID, VerseRef) — where in Torah this mitzvah is grounded +%% Beliefs and Foundations mitzvah_source(1, ref(shemot, 20, 2)). % Anochi Hashem Elokecha -mitzvah_source(2, ref(shemot, 20, 3)). % Lo yihyeh lecha -mitzvah_source(3, ref(devarim, 6, 4)). % Shema Yisrael -mitzvah_source(4, ref(devarim, 6, 5)). % V'ahavta -mitzvah_source(5, ref(devarim, 6, 13)). % Et Hashem Elokecha tira -mitzvah_source(154, ref(shemot, 20, 8)). % Zachor et yom haShabbat -mitzvah_source(155, ref(shemot, 20, 10)). % Lo ta'aseh kol melachah -mitzvah_source(175, ref(devarim, 16, 18)). % Shoftim v'shotrim -mitzvah_source(289, ref(shemot, 20, 13)). % Lo tirtzach -mitzvah_source(330, ref(shemot, 20, 14)). % Lo tinaf -mitzvah_source(247, ref(shemot, 20, 15)). % Lo tignov -mitzvah_source(285, ref(shemot, 20, 16)). % Lo ta'aneh -mitzvah_source(243, ref(shemot, 20, 17)). % Lo tachmod -mitzvah_source(134, ref(shemot, 23, 11)). % V'hashvi'it tishm'tenah -mitzvah_source(62, ref(vayikra, 1, 3)). % Olah -mitzvah_source(64, ref(vayikra, 4, 27)). % Chatat -mitzvah_source(125, ref(devarim, 26, 2)). % Bikurim -mitzvah_source(126, ref(devarim, 26, 5)). % Arami oved avi -mitzvah_source(295, ref(devarim, 25, 12)). % Save the pursued +mitzvah_source(2, ref(devarim, 6, 4)). % Shema Yisrael — unity +mitzvah_source(3, ref(devarim, 6, 5)). % V'ahavta — love +mitzvah_source(4, ref(devarim, 6, 13)). % Et Hashem Elokecha tira — fear +mitzvah_source(5, ref(shemot, 23, 25)). % Va'avadetem — prayer +mitzvah_source(6, ref(devarim, 10, 20)). % U'vo tidbak — cleave +mitzvah_source(9, ref(vayikra, 22, 32)). % V'nikdashti — sanctify +mitzvah_source(10, ref(devarim, 6, 7)). % V'shinantam — shema +mitzvah_source(11, ref(devarim, 6, 7)). % V'shinantam — study + +%% Torah objects +mitzvah_source(13, ref(devarim, 6, 8)). % Tefillin +mitzvah_source(15, ref(bamidbar, 15, 38)). % Tzitzit +mitzvah_source(16, ref(devarim, 6, 9)). % Mezuzah +mitzvah_source(18, ref(devarim, 31, 19)). % Write Torah + +%% Temple and Sanctuary +mitzvah_source(20, ref(shemot, 25, 8)). % V'asu li mikdash +mitzvah_source(26, ref(bamidbar, 6, 23)). % Birkat kohanim + +%% Offerings +mitzvah_source(64, ref(vayikra, 1, 3)). % Olah +mitzvah_source(65, ref(vayikra, 4, 27)). % Chatat +mitzvah_source(68, ref(vayikra, 3, 1)). % Shelamim + +%% Agriculture +mitzvah_source(114, ref(bamidbar, 18, 12)). % Terumah +mitzvah_source(122, ref(shemot, 23, 11)). % Shmitah +mitzvah_source(125, ref(devarim, 26, 2)). % Bikurim +mitzvah_source(126, ref(devarim, 26, 5)). % Arami oved avi +mitzvah_source(128, ref(vayikra, 19, 9)). % Pe'ah +mitzvah_source(136, ref(vayikra, 23, 15)). % Count omer + +%% Shabbat and Festivals +mitzvah_source(138, ref(shemot, 12, 18)). % Matzah +mitzvah_source(139, ref(shemot, 13, 8)). % Tell exodus +mitzvah_source(149, ref(vayikra, 23, 42)). % Sukkah +mitzvah_source(150, ref(vayikra, 23, 40)). % Lulav +mitzvah_source(151, ref(bamidbar, 29, 1)). % Shofar +mitzvah_source(154, ref(shemot, 20, 8)). % Zachor — Shabbat rest +mitzvah_source(155, ref(shemot, 20, 8)). % Kiddush +mitzvah_source(161, ref(bereishit, 17, 10)). % Circumcision + +%% Justice +mitzvah_source(165, ref(devarim, 16, 18)). % Shoftim v'shotrim +mitzvah_source(178, ref(devarim, 16, 20)). % Tzedek tzedek tirdof + +%% Interpersonal +mitzvah_source(181, ref(devarim, 15, 8)). % Open your hand +mitzvah_source(191, ref(vayikra, 19, 17)). % Rebuke +mitzvah_source(192, ref(vayikra, 19, 18)). % Love your neighbor +mitzvah_source(196, ref(shemot, 20, 12)). % Honor parents +mitzvah_source(241, ref(bamidbar, 35, 11)). % Cities of refuge +mitzvah_source(248, ref(devarim, 4, 9)). % Guard your life + +%% Key Prohibitions +mitzvah_source(249, ref(shemot, 20, 3)). % Lo yihyeh lecha — no other gods +mitzvah_source(250, ref(shemot, 20, 4)). % Lo ta'aseh — no idols +mitzvah_source(289, ref(devarim, 22, 11)). % Shaatnez +mitzvah_source(307, ref(shemot, 22, 27)). % Not blaspheme +mitzvah_source(309, ref(shemot, 20, 7)). % Not take name in vain +mitzvah_source(310, ref(vayikra, 22, 32)). % Not profane the name +mitzvah_source(374, ref(shemot, 13, 3)). % Not eat chametz +mitzvah_source(418, ref(vayikra, 19, 11)). % Not steal +mitzvah_source(420, ref(devarim, 19, 14)). % Not move boundary +mitzvah_source(439, ref(vayikra, 19, 15)). % Judge not unjust +mitzvah_source(440, ref(shemot, 23, 8)). % Not accept bribe +mitzvah_source(449, ref(shemot, 20, 16)). % Not bear false witness +mitzvah_source(461, ref(shemot, 20, 13)). % Not murder +mitzvah_source(468, ref(vayikra, 19, 16)). % Not stand by blood +mitzvah_source(472, ref(vayikra, 19, 16)). % Not gossip +mitzvah_source(473, ref(vayikra, 19, 17)). % Not hate in heart +mitzvah_source(475, ref(vayikra, 19, 18)). % Not take revenge +mitzvah_source(491, ref(shemot, 20, 14)). % Not commit adultery +mitzvah_source(532, ref(vayikra, 18, 6)). % Maintain boundaries +mitzvah_source(551, ref(vayikra, 11, 4)). % Not eat non-kosher +mitzvah_source(561, ref(vayikra, 17, 12)). % Not eat blood +mitzvah_source(564, ref(shemot, 23, 19)). % Not eat meat and milk %% ============================================================ %% QUERIES @@ -172,6 +785,6 @@ mitzvah_source(295, ref(devarim, 25, 12)). % Save the pursued mitzvah_category_count(Category, Count) :- aggregate_all(count, mitzvah(_, Category, _, _), Count). -%% Total encoded in this Phase 1 subset +%% Total encoded total_encoded(Count) :- aggregate_all(count, mitzvah(_, _, _, _), Count). diff --git a/talmudic_engine/src/specification/relationships.pl b/talmudic_engine/src/specification/relationships.pl index 083c78ee..a08e2dca 100644 --- a/talmudic_engine/src/specification/relationships.pl +++ b/talmudic_engine/src/specification/relationships.pl @@ -3,6 +3,9 @@ %% These relationships encode structural connections between %% commandments and between roots that the reasoning engine %% uses for interpretation and challenge generation. +%% +%% Phase 3: Updated for full 613 mitzvot numbering. +%% Positive: 1-248, Prohibition: 249-613. :- module(relationships, [ mitzvah_grounds/2, @@ -10,7 +13,8 @@ root_shares_consonants/3, mitzvah_domain/2, complementary_mitzvot/2, - domain_mitzvot/2 + domain_mitzvot/2, + action_domain/2 ]). :- use_module(mitzvot). @@ -33,26 +37,38 @@ mitzvah_grounds(MitzvahID, ref(Book, Ch, Vs)) :- %% These are not errors — they are productive tensions %% that the dialectical engine resolves or marks teiku. -%% Justice vs mercy -mitzvah_conflicts_with(179, 295, +%% Justice vs mercy — judge_righteously(178) vs not_fail_to_save_pursued(489) +mitzvah_conflicts_with(178, 489, 'Judging righteously may conflict with saving the pursued when the pursued is also guilty'). -%% Following majority vs preventing evil -mitzvah_conflicts_with(181, 182, +%% Following majority vs preventing evil — follow_majority(175) vs not_follow_majority_for_evil(450) +mitzvah_conflicts_with(175, 450, 'Following the majority in court conflicts with not following the majority for evil'). -%% Sanctifying the name vs preserving life -mitzvah_conflicts_with(6, 289, +%% Sanctifying the name vs preserving life — sanctify_the_name(9) vs not_murder(461) +mitzvah_conflicts_with(9, 461, 'Sanctifying the name through martyrdom conflicts with the prohibition against allowing death'). -%% Shabbat rest vs saving life (pikuach nefesh) -mitzvah_conflicts_with(155, 295, - 'Not working on Shabbat conflicts with saving the pursued when rescue requires work'). +%% Shabbat rest vs saving life (pikuach nefesh) — rest_on_shabbat(154) vs not_stand_idly_by_blood(468) +mitzvah_conflicts_with(154, 468, + 'Resting on Shabbat conflicts with not standing idly by when life is threatened'). -%% Loving your neighbor vs administering justice -mitzvah_conflicts_with(4, 179, +%% Loving your neighbor vs administering justice — love_fellow_jew(192) vs judge_righteously(178) +mitzvah_conflicts_with(192, 178, 'Love may conflict with righteous judgment when judgment causes pain to the beloved'). +%% Charity vs self-preservation — give_tzedakah(181) vs guard_ones_life(248) +mitzvah_conflicts_with(181, 248, + 'Obligation to give charity conflicts with protecting ones own sustenance'). + +%% Rebuke vs not shaming — rebuke_sinner(191) vs not_shame_fellow_publicly(474) +mitzvah_conflicts_with(191, 474, + 'Obligation to rebuke a sinner conflicts with prohibition against public shaming'). + +%% King obedience vs not following idolatry — obey_king(218) vs no_other_gods(249) +mitzvah_conflicts_with(218, 249, + 'Obeying the king conflicts with prohibition of idolatry when king commands worship of other gods'). + %% ============================================================ %% ROOT RELATIONSHIPS — consonant sharing %% ============================================================ @@ -82,17 +98,17 @@ action_domain(love_hashem, covenant). action_domain(fear_hashem, authority). action_domain(sanctify_the_name, holiness). action_domain(not_profane_the_name, holiness). -action_domain(hear_shema, knowledge). +action_domain(read_shema, knowledge). action_domain(study_torah, knowledge). action_domain(rest_on_shabbat, holiness). -action_domain(not_work_on_shabbat, holiness). action_domain(sanctify_shabbat, holiness). action_domain(appoint_judges, judgment). -action_domain(not_judge_unjustly, judgment). +action_domain(judge_not_be_unjust, judgment). action_domain(judge_righteously, judgment). action_domain(not_murder, death). action_domain(not_cause_death_of_innocent, death). -action_domain(save_the_pursued, mercy). +action_domain(not_fail_to_save_pursued, mercy). +action_domain(not_stand_idly_by_blood, mercy). action_domain(not_commit_adultery, transgression). action_domain(maintain_boundaries, separation). action_domain(not_bear_false_witness, speech). @@ -101,26 +117,51 @@ action_domain(not_steal, transgression). action_domain(bring_olah, offering). action_domain(bring_chatat, offering). action_domain(bring_bikurim, offering). +action_domain(love_fellow_jew, covenant). +action_domain(rebuke_sinner, covenant). +action_domain(not_gossip, speech). +action_domain(not_hate_in_heart, covenant). +action_domain(give_tzedakah, mercy). +action_domain(not_shame_fellow_publicly, speech). +action_domain(not_take_revenge, covenant). +action_domain(not_bear_grudge, covenant). +action_domain(guard_ones_life, mercy). +action_domain(not_eat_blood, holiness). +action_domain(not_eat_meat_and_milk, holiness). +action_domain(not_make_idols, holiness). +action_domain(not_worship_idols_their_way, holiness). +action_domain(follow_majority_in_court, judgment). +action_domain(not_follow_majority_for_evil, judgment). +action_domain(obey_king, authority). +action_domain(pray_to_hashem, knowledge). +action_domain(teach_torah, knowledge). +action_domain(circumcise_males, covenant). +action_domain(honor_parents, covenant). +action_domain(separate_terumah, offering). %% ============================================================ %% COMPLEMENTARY MITZVOT — mitzvot that strengthen each other %% ============================================================ %% complementary_mitzvot(ID1, ID2) — these work together -complementary_mitzvot(1, 3). % know_hashem + unity_of_hashem -complementary_mitzvot(4, 5). % love_hashem + fear_hashem -complementary_mitzvot(154, 156). % rest_on_shabbat + sanctify_shabbat -complementary_mitzvot(175, 179). % appoint_judges + judge_righteously -complementary_mitzvot(289, 295). % not_murder + save_the_pursued -complementary_mitzvot(125, 126). % bring_bikurim + recite_declaration +complementary_mitzvot(1, 2). % know_hashem + unity_of_hashem +complementary_mitzvot(3, 4). % love_hashem + fear_hashem +complementary_mitzvot(154, 155). % rest_on_shabbat + sanctify_shabbat +complementary_mitzvot(165, 178). % appoint_judges + judge_righteously +complementary_mitzvot(461, 489). % not_murder + not_fail_to_save_pursued +complementary_mitzvot(125, 126). % bring_bikurim + recite_declaration +complementary_mitzvot(191, 192). % rebuke_sinner + love_fellow_jew +complementary_mitzvot(181, 248). % give_tzedakah + guard_ones_life %% Symmetric — explicit reverse facts (no recursive rule, which loops in Prolog) -complementary_mitzvot(3, 1). % unity_of_hashem + know_hashem -complementary_mitzvot(5, 4). % fear_hashem + love_hashem -complementary_mitzvot(156, 154). % sanctify_shabbat + rest_on_shabbat -complementary_mitzvot(179, 175). % judge_righteously + appoint_judges -complementary_mitzvot(295, 289). % save_the_pursued + not_murder -complementary_mitzvot(126, 125). % recite_declaration + bring_bikurim +complementary_mitzvot(2, 1). % unity_of_hashem + know_hashem +complementary_mitzvot(4, 3). % fear_hashem + love_hashem +complementary_mitzvot(155, 154). % sanctify_shabbat + rest_on_shabbat +complementary_mitzvot(178, 165). % judge_righteously + appoint_judges +complementary_mitzvot(489, 461). % not_fail_to_save_pursued + not_murder +complementary_mitzvot(126, 125). % recite_declaration + bring_bikurim +complementary_mitzvot(192, 191). % love_fellow_jew + rebuke_sinner +complementary_mitzvot(248, 181). % guard_ones_life + give_tzedakah %% ============================================================ %% QUERIES diff --git a/talmudic_engine/test/middot_test.pl b/talmudic_engine/test/middot_test.pl new file mode 100644 index 00000000..f1e4217d --- /dev/null +++ b/talmudic_engine/test/middot_test.pl @@ -0,0 +1,353 @@ +%% middot_test.pl — Tests for the 13 Middot of Rabbi Yishmael. +%% +%% Phase 3: Hermeneutical inference predicates. + +:- use_module(library(plunit)). +:- use_module('../src/middot/middot'). +:- use_module('../src/middot/kal_vachomer'). +:- use_module('../src/middot/gezerah_shavah'). +:- use_module('../src/middot/binyan_av'). +:- use_module('../src/middot/klal_ufrat'). +:- use_module('../src/middot/davar_yatza'). +:- use_module('../src/middot/lamed_inyan'). +:- use_module('../src/middot/shnei_ketuvim'). +:- use_module('../src/specification/mitzvot'). +:- use_module('../src/specification/torah_text'). +:- use_module('../src/specification/root_meanings'). + +%% ============================================================ +%% MASTER MODULE TESTS +%% ============================================================ + +:- begin_tests(middot_master). + +%% All 13 middot are named +test(all_thirteen_named) :- + findall(N, middah_name(N, _), Numbers), + length(Numbers, 13). + +%% all_middot returns a list of 13 names +test(all_middot_list) :- + all_middot(Middot), + length(Middot, 13). + +%% Key middot names are correct +test(middah_1_is_kal_vachomer) :- + middah_name(1, kal_vachomer). + +test(middah_2_is_gezerah_shavah) :- + middah_name(2, gezerah_shavah). + +test(middah_13_is_shnei_ketuvim) :- + middah_name(13, shnei_ketuvim). + +%% apply_middah works for rule 1 (kal vachomer) +test(apply_middah_1, [nondet]) :- + apply_middah(1, shabbat_rest, festival_rest, _Reasoning). + +%% apply_middah works for rule 5 (klal ufrat) +test(apply_middah_5, [nondet]) :- + apply_middah(5, + general(fruit_trees), + particular([olive, grape]), + narrowed_to([olive, grape], from(fruit_trees))). + +:- end_tests(middot_master). + + +%% ============================================================ +%% RULE 1: KAL VACHOMER +%% ============================================================ + +:- begin_tests(kal_vachomer_tests). + +%% Severity ordering: monetary < physical < capital < divine +test(monetary_less_than_physical) :- + severity_ordering(monetary, physical). + +test(physical_less_than_capital) :- + severity_ordering(physical, capital). + +test(capital_less_than_divine) :- + severity_ordering(capital, divine). + +%% Transitive stringency +test(monetary_less_than_capital) :- + is_more_stringent(monetary, capital). + +test(monetary_less_than_divine) :- + is_more_stringent(monetary, divine). + +%% Kal vachomer: shabbat → festival +test(shabbat_to_festival) :- + kal_vachomer(shabbat_rest, festival_rest, _, definite). + +%% Kal vachomer: monetary → physical compensation +test(monetary_to_physical) :- + kal_vachomer(compensate_monetary, compensate_physical, _, definite). + +%% Kal vachomer: domain-based derivation +test(domain_derivation, [nondet]) :- + kal_vachomer( + law_in(monetary, _), + law_in(physical, _), + derived(_, from(monetary), to(physical), kal_vachomer), + definite + ). + +%% Unconditional mitzvah implies conditional +test(unconditional_implies_conditional, [nondet]) :- + kal_vachomer( + mitzvah_applies(1, always), + mitzvah_applies(1, when(_)), + derived(1, unconditional_implies_conditional, kal_vachomer), + definite + ). + +%% Dayo principle: derived law equals source law +test(dayo_principle) :- + kal_vachomer:dayo(derived(some_law, _, _, _), some_law). + +:- end_tests(kal_vachomer_tests). + + +%% ============================================================ +%% RULE 2: GEZERAH SHAVAH +%% ============================================================ + +:- begin_tests(gezerah_shavah_tests). + +%% Known gezerah shavah: shabbat ↔ pesach (shemirah) +test(shabbat_pesach_shemirah) :- + gezerah_shavah(shabbat_keeping, pesach_keeping, _, shin_mem_resh). + +%% Known gezerah shavah: shabbat ↔ circumcision (ot) +test(shabbat_circumcision_ot) :- + gezerah_shavah(shabbat_sign, circumcision_sign, _, aleph_vav_tav). + +%% Shared keyword: two verses sharing a root link +test(shared_keyword_creation, [nondet]) :- + shared_keyword(ref(bereishit, 1, 1), ref(bereishit, 1, 27), bet_resh_aleph). + +%% Dynamic gezerah shavah from Torah text +test(dynamic_gezerah_shavah, [nondet]) :- + gezerah_shavah(ref(bereishit, 1, 1), ref(bereishit, 1, 27), _, bet_resh_aleph). + +:- end_tests(gezerah_shavah_tests). + + +%% ============================================================ +%% RULES 3-4: BINYAN AV +%% ============================================================ + +:- begin_tests(binyan_av_tests). + +%% Binyan av from one verse: source verse establishes domain law +%% Using Shemot 20:8 — mitzvah 154 (rest_on_shabbat), root qof_dalet_shin → holiness +test(binyan_av_one_verse, [nondet]) :- + binyan_av_one(ref(shemot, 20, 8), applies_to_domain(_, _), _). + +%% Binyan av from two verses: common root found +test(binyan_av_two_verses, [nondet]) :- + binyan_av_two( + ref(bereishit, 1, 1), + ref(bereishit, 1, 27), + general_rule(bet_resh_aleph, creation), + bet_resh_aleph + ). + +%% Unified interface: single verse +test(binyan_av_single, [nondet]) :- + binyan_av(single_verse(ref(shemot, 20, 8)), _, _). + +%% Unified interface: two verses +test(binyan_av_two_unified, [nondet]) :- + binyan_av( + two_verses(ref(bereishit, 1, 1), ref(bereishit, 1, 27)), + _, + _ + ). + +%% Common principle extraction +test(common_principle_from_list, [nondet]) :- + common_principle( + [ref(bereishit, 1, 1), ref(bereishit, 1, 27)], + bet_resh_aleph, + _ + ). + +:- end_tests(binyan_av_tests). + + +%% ============================================================ +%% RULES 5-8: KLAL UFRAT +%% ============================================================ + +:- begin_tests(klal_ufrat_tests). + +%% Rule 5: General then particular narrows +test(klal_ufrat_narrows) :- + klal_ufrat( + general(fruit_trees), + particular([olive, grape]), + narrowed_to([olive, grape], from(fruit_trees)) + ). + +%% Rule 6: Particular then general expands +test(prat_uklal_expands) :- + prat_uklal( + particular([sheep, cattle]), + general(all_livestock), + expanded_to(all_livestock, including([sheep, cattle])) + ). + +%% Rule 7: General-particular-general yields similar +test(klal_ufrat_uklal_similar) :- + klal_ufrat_uklal( + general(all_damage), + particular([ox_damage, pit_damage, fire_damage]), + general(all_damage), + similar_to([ox_damage, pit_damage, fire_damage], + within(all_damage, negligence_based_damage)) + ). + +%% Generic klal ufrat +test(generic_klal_ufrat) :- + klal_ufrat( + general(any_category), + particular(specific_thing), + narrowed_to(specific_thing, from(any_category)) + ). + +%% Scope results +test(scope_narrowed) :- + scope_result(klal_then_prat, narrowed). + +test(scope_expanded) :- + scope_result(prat_then_klal, expanded). + +test(scope_similar) :- + scope_result(klal_prat_klal, similar). + +:- end_tests(klal_ufrat_tests). + + +%% ============================================================ +%% RULES 9-11: DAVAR YATZA +%% ============================================================ + +:- begin_tests(davar_yatza_tests). + +%% Rule 9: Exception teaches about the general +test(exception_teaches_general) :- + davar_yatza_llamed( + exception(chatat, blood_sprinkling_north), + general(all_offerings), + teaches(blood_sprinkling_north, applies_to_all(all_offerings)) + ). + +%% Generic rule 9 +test(generic_exception_teaches) :- + davar_yatza_llamed( + exception(item, some_law), + general(category), + teaches(some_law, applies_to_all(category)) + ). + +%% Rule 10: Same type reduces severity +test(same_type_reduces) :- + davar_yatza_toan_echad( + exception(item, shared_law), + general(category, shared_law), + reduces(shared_law, for(category), because(item)) + ). + +%% Rule 11: Different type creates dual application +test(different_type_dual_rules) :- + davar_yatza_toan_acher( + exception(metzora, outside_camp_procedure), + general(tumah, standard_purification), + dual_rules(metzora, follows(standard_purification), and(outside_camp_procedure)) + ). + +:- end_tests(davar_yatza_tests). + + +%% ============================================================ +%% RULE 12: LAMED INYAN +%% ============================================================ + +:- begin_tests(lamed_inyan_tests). + +%% "Lo tignov" in context of capital crimes = kidnapping +test(lo_tignov_kidnapping) :- + lamed_me_inyano( + ref(shemot, 20, 15), + context(capital_crimes_sequence), + meaning(lo_tignov, refers_to(kidnapping), not(ordinary_theft)) + ). + +%% Context from surrounding verses (requires prev and next verse to exist) +test(context_from_surrounding, [nondet]) :- + lamed_me_inyano( + ref(shemot, 20, 14), + context(ref(shemot, 20, 13), ref(shemot, 20, 15)), + meaning_from(context, ref(shemot, 20, 14)) + ). + +%% Lamed misofo: conclusion clarifies ambiguous topic +test(conclusion_clarifies) :- + lamed_misofo( + ambiguous(topic), + concludes_with(clarification), + meaning(topic, clarified_by(clarification)) + ). + +%% Unified context_determines_meaning +test(context_determines_surrounding, [nondet]) :- + context_determines_meaning( + ref(shemot, 20, 15), + surrounding, + meaning(lo_tignov, refers_to(kidnapping), not(ordinary_theft)) + ). + +:- end_tests(lamed_inyan_tests). + + +%% ============================================================ +%% RULE 13: SHNEI KETUVIM +%% ============================================================ + +:- begin_tests(shnei_ketuvim_tests). + +%% Domains in tension +test(judgment_mercy_tension) :- + domains_in_tension(judgment, mercy). + +test(mercy_judgment_tension) :- + domains_in_tension(mercy, judgment). + +test(holiness_transgression_tension) :- + domains_in_tension(holiness, transgression). + +%% Two verses with roots in opposing domains contradict +test(verses_contradict_detection, [nondet]) :- + verses_contradict(V1, V2, domain_conflict(_, _)), + V1 \= V2. + +%% Resolving verse shares roots with both +test(resolving_verse_found, [nondet]) :- + resolving_verse(V1, V2, V3), + V1 \= V3, + V2 \= V3. + +%% Shnei ketuvim unified interface — harmonized case +test(shnei_ketuvim_harmonized, [nondet]) :- + shnei_ketuvim( + contradicting(V1, V2), + harmonized_reading(V1, V2, _V3), + reasoning(V1, contradicts(V2), resolved_by(_)), + _ + ). + +:- end_tests(shnei_ketuvim_tests). diff --git a/talmudic_engine/test/mitzvot_test.pl b/talmudic_engine/test/mitzvot_test.pl index abfde29c..7e955f06 100644 --- a/talmudic_engine/test/mitzvot_test.pl +++ b/talmudic_engine/test/mitzvot_test.pl @@ -1,4 +1,7 @@ %% mitzvot_test.pl — Tests for the specification layer. +%% +%% Phase 3: Updated for full 613 mitzvot encoding. +%% Numbering: Positive 1-248, Prohibition 249-613. :- use_module(library(plunit)). :- use_module('../src/specification/mitzvot'). @@ -8,41 +11,62 @@ :- begin_tests(mitzvot). -%% The specification has mitzvot -test(mitzvot_exist) :- - total_encoded(Count), - Count > 0. +%% The specification has exactly 613 mitzvot +test(total_613) :- + total_encoded(613). -%% The three categories exist +%% The two categories exist test(positive_mitzvot_exist) :- mitzvah(_, positive, _, _). test(prohibition_mitzvot_exist) :- mitzvah(_, prohibition, _, _). -test(belief_mitzvot_exist) :- - mitzvah(_, belief, _, _). +%% Category counts match Rambam +test(positive_count) :- + mitzvah_category_count(positive, 248). -%% The first mitzvah is know_hashem +test(prohibition_count) :- + mitzvah_category_count(prohibition, 365). + +%% The first mitzvah is know_hashem (Rambam Positive #1) test(first_mitzvah) :- - mitzvah(1, belief, know_hashem, always). + mitzvah(1, positive, know_hashem, always). + +%% Core beliefs +test(unity_of_hashem) :- + mitzvah(2, positive, unity_of_hashem, always). + +test(love_hashem) :- + mitzvah(3, positive, love_hashem, always). + +test(fear_hashem) :- + mitzvah(4, positive, fear_hashem, always). %% Shabbat mitzvot exist test(shabbat_rest) :- mitzvah(154, positive, rest_on_shabbat, when(seventh_day)). -test(shabbat_no_work) :- - mitzvah(155, prohibition, not_work_on_shabbat, when(seventh_day)). +test(sanctify_shabbat) :- + mitzvah(155, positive, sanctify_shabbat, when(seventh_day)). %% The three halt conditions have their mitzvot +%% (Prohibitions are numbered 249-613) test(no_other_gods) :- - mitzvah(2, prohibition, no_other_gods, always). + mitzvah(249, prohibition, no_other_gods, always). -test(no_murder) :- - mitzvah(289, prohibition, not_murder, always). +test(not_murder) :- + mitzvah(461, prohibition, not_murder, always). -test(no_adultery) :- - mitzvah(330, prohibition, not_commit_adultery, always). +test(not_commit_adultery) :- + mitzvah(491, prohibition, not_commit_adultery, always). + +%% Additional halt-related +test(not_make_idols) :- + mitzvah(250, prohibition, not_make_idols, always). + +test(maintain_boundaries) :- + mitzvah(532, prohibition, maintain_boundaries, always). %% Source references exist test(mitzvah_sources_exist) :- @@ -51,6 +75,48 @@ test(mitzvah_sources_exist) :- test(shabbat_source) :- mitzvah_source(154, ref(shemot, 20, 8)). +test(murder_source) :- + mitzvah_source(461, ref(shemot, 20, 13)). + +%% Korbanot +test(olah_exists) :- + mitzvah(64, positive, bring_olah, when(offering_required)). + +test(chatat_exists) :- + mitzvah(65, positive, bring_chatat, when(unintentional_sin)). + +%% Agriculture +test(bikurim_exists) :- + mitzvah(125, positive, bring_bikurim, when(first_fruits_available)). + +test(shmitah_exists) :- + mitzvah(122, positive, let_land_rest_shmitah, when(seventh_year)). + +%% Justice +test(appoint_judges) :- + mitzvah(165, positive, appoint_judges, always). + +test(not_accept_bribe) :- + mitzvah(440, prohibition, judge_not_accept_bribe, always). + +%% Interpersonal +test(love_fellow) :- + mitzvah(192, positive, love_fellow_jew, always). + +test(not_gossip) :- + mitzvah(472, prohibition, not_gossip, always). + +%% Kashrut +test(not_eat_blood) :- + mitzvah(561, prohibition, not_eat_blood, always). + +test(not_eat_meat_milk) :- + mitzvah(564, prohibition, not_eat_meat_and_milk, always). + +%% Last mitzvah +test(last_mitzvah) :- + mitzvah(613, prohibition, not_eat_sanctified_that_became_tamei, when(offering)). + :- end_tests(mitzvot). @@ -105,13 +171,13 @@ test(kadash_gematria) :- :- begin_tests(relationships). -%% Tensions exist +%% Tensions exist (updated IDs for Phase 3 numbering) test(justice_mercy_tension) :- - mitzvah_conflicts_with(179, 295, _). + mitzvah_conflicts_with(178, 489, _). %% Complementary mitzvot test(complementary) :- - complementary_mitzvot(1, 3). + complementary_mitzvot(1, 2). %% Root consonant sharing test(consonant_sharing) :- diff --git a/talmudic_engine/test/phase3_verify_test.pl b/talmudic_engine/test/phase3_verify_test.pl new file mode 100644 index 00000000..bd1c19c5 --- /dev/null +++ b/talmudic_engine/test/phase3_verify_test.pl @@ -0,0 +1,213 @@ +%% phase3_verify_test.pl — Phase 3 verification tests. +%% +%% Architecture §4, Step 20: Verify the system can: +%% 1. Deliberate a case through full dialectical process +%% 2. Produce majority decision with preserved dissent +%% 3. Apply middot-based reasoning +%% 4. Run diagnostic protocol +%% 5. Query 613 mitzvot by domain, condition, category + +:- use_module(library(plunit)). +:- use_module('../src/reasoning/interpret'). +:- use_module('../src/reasoning/challenge'). +:- use_module('../src/reasoning/resolve'). +:- use_module('../src/reasoning/teiku'). +:- use_module('../src/specification/mitzvot'). +:- use_module('../src/specification/torah_text'). +:- use_module('../src/specification/relationships'). +:- use_module('../src/specification/root_meanings'). +:- use_module('../src/middot/middot'). +:- use_module('../src/middot/kal_vachomer'). +:- use_module('../src/middot/gezerah_shavah'). +:- use_module('../src/middot/shnei_ketuvim'). +:- use_module('../src/diagnostic/tzaraat'). +:- use_module('../src/diagnostic/inspection'). +:- use_module('../src/diagnostic/diagnosis'). + +%% ============================================================ +%% STEP 20: FULL DELIBERATION CYCLE +%% ============================================================ + +:- begin_tests(full_deliberation). + +%% A case about holiness can be interpreted +test(interpret_holiness, [nondet]) :- + Case = case(verify_holiness, holiness, [qof_dalet_shin], + 'What does it mean to be holy?'), + interpret(Case, interpretation(verify_holiness, _, _, _, _)). + +%% A case about judgment produces a challenge +test(judgment_case_challenged, [nondet]) :- + Case = case(verify_judgment, judgment, [shin_pe_tet, tzade_dalet_qof], + 'How to judge righteously?'), + interpret(Case, Interpretation), + challenge(Interpretation, kushya(_, _, _)). + +%% A case can go through full resolution +test(full_resolve_cycle, [nondet]) :- + Case = case(verify_resolve, holiness, [qof_dalet_shin], + 'What is the holiness obligation?'), + resolve(Case, Resolution), + ( Resolution = accepted(_) + ; Resolution = challenged(_, _) + ; Resolution = synthesized(_, _, _) + ; Resolution = teiku(_) + ). + +%% Teiku count is tracked +test(teiku_tracking) :- + teiku_count(Count), + integer(Count). + +:- end_tests(full_deliberation). + + +%% ============================================================ +%% STEP 20: 613 MITZVOT QUERYABILITY +%% ============================================================ + +:- begin_tests(mitzvot_queryability). + +%% Query all mitzvot in a domain +test(query_by_domain, [nondet]) :- + domain_mitzvot(judgment, Mitzvot), + Mitzvot \= []. + +%% Query mitzvot by category +test(query_positives) :- + findall(ID, mitzvah(ID, positive, _, _), IDs), + length(IDs, 248). + +test(query_prohibitions) :- + findall(ID, mitzvah(ID, prohibition, _, _), IDs), + length(IDs, 365). + +%% Query conditional mitzvot +test(query_conditional, [nondet]) :- + mitzvah(_, _, _, when(_)). + +%% Query unconditional mitzvot +test(query_unconditional, [nondet]) :- + mitzvah(_, _, _, always). + +%% Mitzvah source grounding +test(sources_exist) :- + findall(ID, mitzvah_source(ID, _), IDs), + length(IDs, Count), + Count > 50. %% At least 50 mitzvot have sources + +%% Complementary pairs exist +test(complementary_pairs) :- + findall(pair(A,B), complementary_mitzvot(A, B), Pairs), + length(Pairs, Count), + Count >= 16. %% 8 pairs * 2 directions + +%% Tension pairs exist +test(tension_pairs) :- + findall(pair(A,B), mitzvah_conflicts_with(A, B, _), Pairs), + length(Pairs, Count), + Count >= 8. + +:- end_tests(mitzvot_queryability). + + +%% ============================================================ +%% STEP 20: MIDDOT APPLICATION +%% ============================================================ + +:- begin_tests(middot_application). + +%% All 13 middot are enumerated +test(all_13_enumerated) :- + all_middot(M), + length(M, 13). + +%% Kal vachomer produces derivation +test(kal_vachomer_derivation) :- + kal_vachomer(shabbat_rest, festival_rest, Derived, definite), + Derived = derived(rest_obligation, from(shabbat), to(festival), kal_vachomer). + +%% Gezerah shavah finds verbal link +test(gezerah_shavah_link) :- + gezerah_shavah(shabbat_keeping, pesach_keeping, _, shin_mem_resh). + +%% Gezerah shavah from Torah text +test(dynamic_verbal_link, [nondet]) :- + shared_keyword(ref(bereishit, 1, 1), ref(bereishit, 1, 27), bet_resh_aleph). + +%% Shnei ketuvim: domain tensions known +test(domain_tensions_known) :- + domains_in_tension(judgment, mercy), + domains_in_tension(holiness, transgression). + +%% Challenge module has middot-based strategies +test(challenge_has_kal_vachomer_strategy) :- + challenge_strength(contradiction(kal_vachomer_tension, _, _, _), strong). + +test(challenge_has_shnei_ketuvim_strategy) :- + challenge_strength(contradiction(shnei_ketuvim_tension, _, _, _), strong). + +:- end_tests(middot_application). + + +%% ============================================================ +%% STEP 20: TZARA'AT DIAGNOSTIC +%% ============================================================ + +:- begin_tests(tzaraat_diagnostic). + +%% Clean input passes +test(clean_input_passes) :- + diagnose(input(declared, [visible], within_bounds, []), declared_tahor). + +%% Impure input rejected +test(impure_input_rejected) :- + diagnose(input(undeclared, [visible], within_bounds, []), confirmed_tamei). + +%% Ambiguous input quarantined +test(ambiguous_input_quarantined) :- + diagnose(input(declared, [hidden], within_bounds, []), requires_quarantine(quarantine_1)). + +%% The paradox: full visibility = purity +test(full_visibility_paradox) :- + diagnose( + input(undeclared, [hidden], exceeds_bounds, [leaks_implementation]), + fully_visible_tahor + ). + +%% 8 diagnosis states +test(eight_states) :- + findall(S, diagnosis_state(S), States), + length(States, 8). + +:- end_tests(tzaraat_diagnostic). + + +%% ============================================================ +%% STEP 20: ROOT AND VERSE QUERYABILITY +%% ============================================================ + +:- begin_tests(root_verse_queries). + +%% All semantic domains +test(domains_exist) :- + all_domains(Domains), + length(Domains, Count), + Count >= 10. + +%% Roots in a domain +test(roots_in_holiness, [nondet]) :- + roots_in_domain(holiness, Roots), + Roots \= []. + +%% Verses mentioning a root +test(verses_with_kadosh, [nondet]) :- + verses_mentioning_root(qof_dalet_shin, Verses), + Verses \= []. + +%% Verse roots can be retrieved +test(verse_roots_retrieved) :- + verse_roots(bereishit, 1, 1, Roots), + member(bet_resh_aleph, Roots). + +:- end_tests(root_verse_queries). diff --git a/talmudic_engine/test/tzaraat_test.pl b/talmudic_engine/test/tzaraat_test.pl new file mode 100644 index 00000000..f5282898 --- /dev/null +++ b/talmudic_engine/test/tzaraat_test.pl @@ -0,0 +1,202 @@ +%% tzaraat_test.pl — Tests for the Tzara'at diagnostic protocol. +%% +%% Phase 3, Step 19: Multi-stage input validation. + +:- use_module(library(plunit)). +:- use_module('../src/diagnostic/tzaraat'). +:- use_module('../src/diagnostic/diagnosis'). +:- use_module('../src/diagnostic/inspection'). +:- use_module('../src/diagnostic/quarantine'). + +%% ============================================================ +%% DIAGNOSIS STATE TESTS +%% ============================================================ + +:- begin_tests(diagnosis_states). + +%% All 8 states exist +test(all_states_exist) :- + findall(S, diagnosis_state(S), States), + length(States, 8). + +%% Terminal states +test(tamei_is_terminal) :- + terminal_state(confirmed_tamei). + +test(tahor_is_terminal) :- + terminal_state(declared_tahor). + +test(fully_visible_is_terminal) :- + terminal_state(fully_visible_tahor). + +%% Initial state +test(initial_state_is_inspection) :- + initial_state(initial_inspection). + +%% Valid transitions +test(initial_to_quarantine) :- + valid_transition(initial_inspection, quarantine_1). + +test(initial_to_tamei) :- + valid_transition(initial_inspection, confirmed_tamei). + +test(initial_to_tahor) :- + valid_transition(initial_inspection, declared_tahor). + +test(initial_to_fully_visible) :- + valid_transition(initial_inspection, fully_visible_tahor). + +test(quarantine_1_to_reinspection) :- + valid_transition(quarantine_1, reinspection_1). + +test(quarantine_2_to_final_reinspection) :- + valid_transition(quarantine_2, reinspection_2). + +%% Transition reasons exist +test(transition_has_reason) :- + transition_reason(initial_inspection, quarantine_1, Reason), + Reason \= ''. + +:- end_tests(diagnosis_states). + + +%% ============================================================ +%% INSPECTION TESTS +%% ============================================================ + +:- begin_tests(inspection_tests). + +%% Clean input → declared tahor +test(clean_input_tahor) :- + Input = input(declared, [visible, visible], within_bounds, []), + inspect(Input, declared_tahor). + +%% Undeclared source → confirmed tamei (high severity) +test(undeclared_source_tamei) :- + Input = input(undeclared, [visible], within_bounds, []), + inspect(Input, confirmed_tamei). + +%% Hidden dependency only → quarantine (moderate severity) +test(hidden_dep_quarantine) :- + Input = input(declared, [hidden], within_bounds, []), + inspect(Input, quarantine_1). + +%% Scope creep → quarantine (moderate severity) +test(scope_creep_quarantine) :- + Input = input(declared, [visible], exceeds_bounds, []), + inspect(Input, quarantine_1). + +%% The paradox: ALL signs present → fully visible tahor +test(fully_visible_paradox) :- + Input = input(undeclared, [hidden], exceeds_bounds, [leaks_implementation]), + inspect(Input, fully_visible_tahor). + +%% Low severity only → declared tahor +test(low_severity_tahor) :- + Input = input(declared, [visible], within_bounds, [leaks_implementation]), + inspect(Input, declared_tahor). + +%% Sign detection +test(detect_undeclared_source) :- + has_sign(input(undeclared, [], within_bounds, []), undeclared_source). + +test(detect_hidden_dependency) :- + has_sign(input(declared, [hidden], within_bounds, []), hidden_dependency). + +test(detect_scope_creep) :- + has_sign(input(declared, [], exceeds_bounds, []), scope_creep). + +test(detect_exposed_internals) :- + has_sign(input(declared, [], within_bounds, [leaks_implementation]), exposed_internals). + +%% Sign count +test(clean_has_zero_signs) :- + count_signs(input(declared, [visible], within_bounds, []), 0). + +test(all_signs_count_four) :- + count_signs(input(undeclared, [hidden], exceeds_bounds, [leaks_implementation]), 4). + +:- end_tests(inspection_tests). + + +%% ============================================================ +%% QUARANTINE TESTS +%% ============================================================ + +:- begin_tests(quarantine_tests). + +%% Can quarantine an input +test(quarantine_creates_record, + [cleanup(retractall(quarantine:quarantine_record(_, _, _, _)))]) :- + retractall(quarantine:quarantine_record(_, _, _, _)), + Input = input(declared, [hidden], within_bounds, []), + quarantine_input(test_q1, Input, quarantine_1), + quarantine:quarantine_record(test_q1, quarantine_1, Signs, 1), + member(hidden_dependency, Signs). + +%% Reinspection: signs cleared → tahor +test(reinspect_cleared_tahor, + [cleanup(retractall(quarantine:quarantine_record(_, _, _, _)))]) :- + retractall(quarantine:quarantine_record(_, _, _, _)), + Input1 = input(declared, [hidden], within_bounds, []), + quarantine_input(test_r1, Input1, quarantine_1), + %% After quarantine, input is clean + Input2 = input(declared, [visible], within_bounds, []), + reinspect(test_r1, Input2, declared_tahor). + +%% Reinspection: signs spread → tamei +test(reinspect_spread_tamei, + [cleanup(retractall(quarantine:quarantine_record(_, _, _, _)))]) :- + retractall(quarantine:quarantine_record(_, _, _, _)), + Input1 = input(declared, [hidden], within_bounds, []), + quarantine_input(test_r2, Input1, quarantine_1), + %% After quarantine, more problems appeared + Input2 = input(declared, [hidden], exceeds_bounds, [leaks_implementation]), + reinspect(test_r2, Input2, confirmed_tamei). + +:- end_tests(quarantine_tests). + + +%% ============================================================ +%% TZARA'AT MASTER MODULE TESTS +%% ============================================================ + +:- begin_tests(tzaraat_master). + +%% Clean input diagnosed immediately +test(diagnose_clean) :- + Input = input(declared, [visible], within_bounds, []), + diagnose(Input, declared_tahor). + +%% Impure input diagnosed immediately +test(diagnose_impure) :- + Input = input(undeclared, [visible], within_bounds, []), + diagnose(Input, confirmed_tamei). + +%% Ambiguous input requires quarantine +test(diagnose_ambiguous) :- + Input = input(declared, [hidden], within_bounds, []), + diagnose(Input, requires_quarantine(quarantine_1)). + +%% Full diagnostic flow: clean input +test(full_flow_clean) :- + Input = input(declared, [visible], within_bounds, []), + full_diagnostic_flow(flow_clean, [Input], declared_tahor). + +%% Full diagnostic flow: immediate tamei +test(full_flow_tamei) :- + Input = input(undeclared, [visible], within_bounds, []), + full_diagnostic_flow(flow_tamei, [Input], confirmed_tamei). + +%% Full diagnostic flow: fully visible paradox +test(full_flow_paradox) :- + Input = input(undeclared, [hidden], exceeds_bounds, [leaks_implementation]), + full_diagnostic_flow(flow_paradox, [Input], fully_visible_tahor). + +%% Full diagnostic flow: quarantine then cleared +test(full_flow_quarantine_cleared, [cleanup(retractall(quarantine_record(_, _, _, _)))]) :- + Input1 = input(declared, [hidden], within_bounds, []), + Input2 = input(declared, [visible], within_bounds, []), + full_diagnostic_flow(flow_q_clear, [Input1, Input2], declared_tahor). + +:- end_tests(tzaraat_master).