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>
This commit is contained in:
Scott KarpandClaude Fable 5.1 committed 2026-10-19 18:25:17 +00:00
1 parent 4bffa01e0e
commit e01181959d
3 files changed
+108 -6

No files matched your search

+18
View File
@@ -45,6 +45,24 @@ process_request(request(resolve, CaseRef, Domain, Roots, Question), Response) :-
; Response = response(error, no_resolution, CaseRef) ; 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) :- process_request(request(halt_check, Action), Response) :-
format_halt_check(Action, Response). format_halt_check(Action, Response).
+41 -6
View File
@@ -153,11 +153,15 @@ read_coupling_term(Str, Term) :-
%% JSON format (Construction §3.3): %% JSON format (Construction §3.3):
%% { "status": "resolved", "interpretation": { ... } } %% { "status": "resolved", "interpretation": { ... } }
%% Interpreted response %% Interpreted response — and the same shape under the names the
response_to_json(response(ok, interpreted, result(ref(Ref), mitzvot(Mitzvot), %% resolve and challenge steps give it when the reading stands
verses(Verses), reading(Reading), %% (tablet 55: resolved_accepted had no clause, so a resolve that
confidence(Conf))), %% succeeded came back UNEXPECTED_RESPONSE; no_challenge is new).
response_to_json(response(ok, Kind, result(ref(Ref), mitzvot(Mitzvot),
verses(Verses), reading(Reading),
confidence(Conf))),
Dict) :- Dict) :-
memberchk(Kind, [interpreted, resolved_accepted, no_challenge]),
maplist(term_to_string, Mitzvot, MitzvotStrs), maplist(term_to_string, Mitzvot, MitzvotStrs),
maplist(term_to_string, Verses, VerseStrs), maplist(term_to_string, Verses, VerseStrs),
term_to_string(Reading, ReadingStr), term_to_string(Reading, ReadingStr),
@@ -171,21 +175,52 @@ response_to_json(response(ok, interpreted, result(ref(Ref), mitzvot(Mitzvot),
confidence: ConfStr}, confidence: ConfStr},
challenge: null}. challenge: null}.
%% Challenged response %% Challenged response — the interpretation's verses and mitzvot are
%% carried, so a judge rejecting on the kushya still cites its ground.
response_to_json(response(ok, resolved_challenged, response_to_json(response(ok, resolved_challenged,
result(interpretation(Interp), challenge(Kushya))), result(interpretation(Interp), challenge(Kushya))),
Dict) :- Dict) :-
Interp = interpretation(_Ref, Mitzvot, Verses, _Reading, _Conf, _Trace),
maplist(term_to_string, Mitzvot, MitzvotStrs),
maplist(term_to_string, Verses, VerseStrs),
term_to_string(Interp, InterpStr), term_to_string(Interp, InterpStr),
term_to_string(Kushya, KushyaStr), term_to_string(Kushya, KushyaStr),
Dict = json{status: "challenged", Dict = json{status: "challenged",
interpretation: json{text: InterpStr, interpretation: json{text: InterpStr,
prolog_form: InterpStr, prolog_form: InterpStr,
grounding: [], grounding: MitzvotStrs,
verses: VerseStrs,
confidence: "medium"}, confidence: "medium"},
challenge: json{kushya: KushyaStr, challenge: json{kushya: KushyaStr,
contradicting: "", contradicting: "",
strength: "moderate"}}. strength: "moderate"}}.
%% Synthesized resolution: both readings stand on common ground.
response_to_json(response(ok, resolved_synthesized,
result(common(Common), verses(Verses), both_sides(Both))),
Dict) :-
maplist(term_to_string, Common, CommonStrs),
maplist(term_to_string, Verses, VerseStrs),
term_to_string(Both, BothStr),
Dict = json{status: "resolved",
interpretation: json{text: BothStr,
prolog_form: BothStr,
grounding: CommonStrs,
verses: VerseStrs,
confidence: "medium"},
challenge: null}.
%% No interpretation possible (from resolve)
response_to_json(response(ok, no_interpretation, result(ref(Ref))), Dict) :-
atom_string(Ref, RefStr),
Dict = json{status: "teiku",
interpretation: json{text: "No interpretation found",
prolog_form: RefStr,
grounding: [],
verses: [],
confidence: "low"},
challenge: null}.
%% Teiku response %% Teiku response
response_to_json(response(ok, teiku, result(record(Record))), Dict) :- response_to_json(response(ok, teiku, result(record(Record))), Dict) :-
term_to_string(Record, RecordStr), term_to_string(Record, RecordStr),
+49
View File
@@ -112,3 +112,52 @@ test(teiku_count_works) :-
integer(Count). integer(Count).
:- end_tests(teiku_module). :- end_tests(teiku_module).
%% ============================================================
%% Tablet 55 — the dialectic over the wire: interpret, challenge,
%% resolve each answer JSON a judge can vote on. Before this the
%% engine had no "challenge" action and a resolve that succeeded came
%% back UNEXPECTED_RESPONSE (resolved_accepted had no JSON clause).
%% ============================================================
:- use_module('../src/interface/api').
:- use_module('../src/interface/json_bridge').
:- use_module('../src/interface/socket_server').
:- begin_tests(dialectic_over_the_wire).
roots_line(Action, Line) :-
format(atom(Line),
'{"action":"~w","case":{"ref":"t55-~w","question":"q","context_roots":["bet-resh-aleph","aleph-lamed-he"]}}',
[Action, Action]).
test(interpret_answers_resolved_with_verses, [nondet]) :-
roots_line(interpret, L),
socket_server:process_json_line(L, R),
get_dict(status, R, "resolved"),
get_dict(interpretation, R, I),
get_dict(verses, I, Vs), Vs \== [].
test(challenge_answers_and_carries_the_ground, [nondet]) :-
roots_line(challenge, L),
socket_server:process_json_line(L, R),
get_dict(status, R, S),
memberchk(S, ["resolved", "challenged"]),
get_dict(interpretation, R, I),
get_dict(verses, I, Vs), Vs \== [].
test(resolve_answers_resolved_not_unexpected, [nondet]) :-
roots_line(resolve, L),
socket_server:process_json_line(L, R),
\+ get_dict(error, R, _),
get_dict(status, R, S),
memberchk(S, ["resolved", "challenged", "teiku"]).
test(no_roots_resolves_on_an_empty_trace, [nondet]) :-
socket_server:process_json_line('{"action":"interpret","case":{"ref":"t55-empty","question":"q","context_roots":[]}}', R),
get_dict(status, R, "resolved"),
get_dict(interpretation, R, I),
get_dict(verses, I, []),
get_dict(grounding, I, []).
:- end_tests(dialectic_over_the_wire).