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 <noreply@anthropic.com>
203 lines
6.8 KiB
Prolog
203 lines
6.8 KiB
Prolog
%% 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).
|