From 83fa5ac46b51c644221cc902d96feacd56014a1d Mon Sep 17 00:00:00 2001 From: Scott Karp Date: Sun, 4 Oct 2026 16:54:38 +0000 Subject: [PATCH] =?UTF-8?q?cycle:=20one=20root,=20once=20=E2=80=94=20a=20v?= =?UTF-8?q?erse=20that=20repeats=20a=20word=20(tablet=2032a)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reading roots from the verse (tablet 32) met a verse that carries אור twice: the real engine answers per word and Bereishit 1:3 came back with א-ו-ר listed twice, each already carrying positions 4 and 6. uniq_by shoresh after normalization. Found by running the built image against the real shoresh-engine binary, not by the suite. 460 tests, 0 failures on seeds 0 42 99. Co-Authored-By: Claude Fable 5.1 --- vav_pipeline/lib/vav_pipeline/bereishit_cycle.ex | 8 +++++++- vav_pipeline/test/tablet32_reference_test.exs | 10 ++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/vav_pipeline/lib/vav_pipeline/bereishit_cycle.ex b/vav_pipeline/lib/vav_pipeline/bereishit_cycle.ex index 8e51ccf0..8be19eab 100644 --- a/vav_pipeline/lib/vav_pipeline/bereishit_cycle.ex +++ b/vav_pipeline/lib/vav_pipeline/bereishit_cycle.ex @@ -156,7 +156,13 @@ defmodule VavPipeline.BereishitCycle do end Map.merge(state, %{ - roots_activated: Enum.map(raw_roots, &normalize_root(&1, context, :engine)), + # A verse may carry the same word twice (אור in Bereishit 1:3); + # the engine answers per word, and each normalized root already + # lists every position. One root, once. + roots_activated: + raw_roots + |> Enum.map(&normalize_root(&1, context, :engine)) + |> Enum.uniq_by(& &1.shoresh), parse_tree: get_result(engine_result, :parse_tree, "parse_tree", nil), dual_readings: get_result(engine_result, :dual_readings, "dual_readings", []), teamim_parse: context.teamim_marks, diff --git a/vav_pipeline/test/tablet32_reference_test.exs b/vav_pipeline/test/tablet32_reference_test.exs index a29981ad..c60940f7 100644 --- a/vav_pipeline/test/tablet32_reference_test.exs +++ b/vav_pipeline/test/tablet32_reference_test.exs @@ -47,6 +47,8 @@ defmodule VavPipeline.Tablet32ReferenceTest do cond do # Devarim 6:5 opens וְאָהַבְתָּ — the engine would find א-ה-ב. String.contains?(text, "ואהבת") -> [root(["aleph", "he", "bet"], "אהב", 8)] + # A verse with a repeated word: the engine answers per word. + String.contains?(text, "אור ויהי אור") -> List.duplicate(root(["aleph", "vav", "resh"], "אור", 207), 2) String.match?(text, ~r/[\x{05D0}-\x{05EA}]/u) -> [root(["bet", "resh", "aleph"], "ברא", 203)] true -> [] end @@ -103,6 +105,14 @@ defmodule VavPipeline.Tablet32ReferenceTest do assert body["answer"] =~ "Devarim 6:5" end + test "a word the verse carries twice is one root, not two" do + conn = post_ask("bereishit 1:3") + body = Jason.decode!(conn.resp_body) + + assert conn.status == 200 + assert length(body["processing"]["roots_consulted"]) == 1 + end + test "English around the reference changes nothing" do conn = post_ask("What does Deuteronomy 6:5 command?") body = Jason.decode!(conn.resp_body)