Files
bikoret/talmudic_engine/src/interface/api.pl
T
Scott KarpandClaude Fable 5.1 e01181959d tablet 55, fourth: the engine answers the whole dialectic over the wire
Live after vav :4bffa01e the judges consulted with roots the engine
could read — interpret found 4 mitzvot and 11 verses for bereishit 1:1
— and the other two seats still said teiku. The engine had no
"challenge" action at all (process_json_line failed and the socket
fell silent), and a resolve that SUCCEEDED came back
UNEXPECTED_RESPONSE because response(ok, resolved_accepted, ...) had
no JSON clause. Both pre-existing; both invisible until a judge asked.

- api.pl: request(challenge, ...) — interpret, then a kushya against
  it → resolved_challenged with the kushya; none → no_challenge with
  the reading.
- json_bridge.pl: interpreted | resolved_accepted | no_challenge share
  the "resolved" JSON; resolved_challenged now carries the
  interpretation's verses and mitzvot (a judge rejecting on the kushya
  cites its ground); resolved_synthesized and no_interpretation gain
  clauses.
- reasoning_test.pl: dialectic_over_the_wire — all three actions
  answer; no roots → resolved on an empty trace (the judge abstains).

Prolog: 7 suites green (bedikah 45, halt 49, middot 47, mitzvot 42,
phase3 28, reasoning 18, tzaraat 34). Local probe: interpret /
challenge / resolve each → resolved, 11 verses, 4 mitzvot.

Live proof waits for tomorrow's manna: today's five panels were all
spent on verification (503 MANNA_DEPLETED, as specified).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-19 18:25:17 +00:00

164 lines
6.9 KiB
Prolog

%% api.pl — JSON API for communication with Elixir.
%%
%% Construction §3.3: JSON over Unix domain socket
%% Protocol: Pipeline sends JSON, engine responds with JSON.
%%
%% Phase 1: Provides a predicate-based interface.
%% Phase 2: Will add the socket listener for the Vav Pipeline.
:- module(api, [
process_request/2,
format_interpretation/2,
format_resolution/2,
format_halt_check/2,
format_interpretation_halt_check/2,
format_given_interpretation_halt_check/2
]).
:- use_module('../reasoning/interpret').
:- use_module('../reasoning/challenge').
:- use_module('../reasoning/resolve').
:- use_module('../halt/avodah_zarah').
:- use_module('../halt/shfichut_damim').
:- use_module('../halt/gilui_arayot').
:- use_module('../halt/structure').
:- use_module('../halt/lo_taaseh_lekha').
:- use_module('../halt/mishkal').
%% ============================================================
%% REQUEST PROCESSING
%% ============================================================
%% Process a request (as a Prolog term matching the JSON schema)
%% Actions: interpret, challenge, resolve, halt_check
process_request(request(interpret, CaseRef, Domain, Roots, Question), Response) :-
Case = case(CaseRef, Domain, Roots, Question),
( interpret(Case, Interpretation)
-> format_interpretation(Interpretation, Response)
; Response = response(error, no_interpretation, CaseRef)
).
process_request(request(resolve, CaseRef, Domain, Roots, Question), Response) :-
Case = case(CaseRef, Domain, Roots, Question),
( resolve(Case, Resolution)
-> format_resolution(Resolution, Response)
; Response = response(error, no_resolution, CaseRef)
).
%% The challenge step of the dialectic, on its own (tablet 55: the
%% Sanhedrin's second seat asks it; until now no handler answered and
%% the socket fell silent). Interpret, then look for a kushya against
%% the interpretation: one stands → resolved_challenged, the kushya
%% named; none → no_challenge, the interpretation as read.
process_request(request(challenge, CaseRef, Domain, Roots, Question), Response) :-
Case = case(CaseRef, Domain, Roots, Question),
( interpret(Case, Interpretation)
-> ( challenge(Interpretation, Kushya)
-> Response = response(ok, resolved_challenged,
result(interpretation(Interpretation),
challenge(Kushya)))
; format_interpretation(Interpretation, response(ok, interpreted, Result)),
Response = response(ok, no_challenge, Result)
)
; Response = response(error, no_interpretation, CaseRef)
).
process_request(request(halt_check, Action), Response) :-
format_halt_check(Action, Response).
process_request(request(halt_check_interpretation, Interpretation), Response) :-
format_interpretation_halt_check(Interpretation, Response).
process_request(request(halt_check_interpretation_given, Interpretation), Response) :-
format_given_interpretation_halt_check(Interpretation, Response).
%% ============================================================
%% RESPONSE FORMATTING
%% ============================================================
%% Format an interpretation as a response
format_interpretation(interpretation(Ref, Mitzvot, Verses, Reading, Confidence, _CouplingTrace),
response(ok, interpreted,
result(ref(Ref),
mitzvot(Mitzvot),
verses(Verses),
reading(Reading),
confidence(Confidence)))).
%% Format a resolution as a response
format_resolution(accepted(Interpretation), Response) :-
format_interpretation(Interpretation, InterpResponse),
InterpResponse = response(ok, interpreted, Result),
Response = response(ok, resolved_accepted, Result).
format_resolution(challenged(Interpretation, Kushya),
response(ok, resolved_challenged,
result(interpretation(Interpretation),
challenge(Kushya)))).
format_resolution(synthesized(CommonMitzvot, Verses, Both),
response(ok, resolved_synthesized,
result(common(CommonMitzvot),
verses(Verses),
both_sides(Both)))).
format_resolution(teiku(Record),
response(ok, teiku,
result(record(Record)))).
format_resolution(no_interpretation(Ref),
response(ok, no_interpretation,
result(ref(Ref)))).
%% Format halt check results — for action-shaped checks
%% (avodah_zarah Form 1, shfichut_damim, gilui_arayot)
format_halt_check(Action, Response) :-
findall(Halt,
( halt_check_avodah_zarah(Action, Halt)
; halt_check_shfichut_damim(Action, Halt)
; halt_check_gilui_arayot(Action, Halt)
; halt_check_parah_adumah(Action, Halt)
; halt_check_carrier_centered(Action, Halt)
; halt_check_chelbenah(Action, Halt)
; halt_check_lo_taaseh_lekha(Action, Halt)
; halt_check_even_vaaven(Action, Halt)
),
Halts),
( Halts = []
-> Response = response(ok, no_halt, action(Action))
; Response = response(halt, violations(Halts), action(Action))
).
%% Format halt check results — for interpretation-shaped checks
%% (avodah_zarah Form 2 = golden_calf, Form 4 = self_grounding).
%%
%% Form 1 fires on actions that name a non-Torah authority.
%% Forms 2 and 4 fire on the *output of reasoning* — an interpretation
%% with empty trace + confidence (golden_calf), or with a non-empty
%% trace whose anchors do not terminate in L1 (self_grounding).
%% Wire-protocol callers should run BOTH format_halt_check (for actions)
%% and format_interpretation_halt_check (for produced interpretations)
%% before treating either as safe.
format_interpretation_halt_check(Interpretation, Response) :-
findall(Halt,
( halt_check_golden_calf(Interpretation, Halt)
; halt_check_self_grounding(Interpretation, Halt)
),
Halts),
( Halts = []
-> Response = response(ok, no_halt, interpretation(Interpretation))
; Response = response(halt, violations(Halts), interpretation(Interpretation))
).
%% The bedikah: an external output against the sources it was GIVEN
%% (avodah_zarah.pl, "forms 2 and 4 for an external output").
format_given_interpretation_halt_check(Interpretation, Response) :-
findall(Halt,
( halt_check_given_golden_calf(Interpretation, Halt)
; halt_check_given_self_grounding(Interpretation, Halt)
),
Halts),
( Halts = []
-> Response = response(ok, no_halt, interpretation(Interpretation))
; Response = response(halt, violations(Halts), interpretation(Interpretation))
).