%% 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)) ).