specs/sugya.md §IV "drives the code", §V step 2. Behaviour unchanged; the reason is now where the behaviour is read from: - @single_witness_forms is gone. Which forms stand on one witness is Sugya.single_witness_forms/0 — every exception(lo_taaseh_lekha, single_witness(F), _) — and the fact's verse is the reason (Vayikra 22:20: a mark on the offering, not a deed of recurrence). - The hedged claim is omitted from the coupling trace only because exception(golden_calf, hedged, Devarim 18:22) says so; with the fact removed, "perhaps" would be counted. - "No sources given and the output invokes none" reports assessed: false only because exception(golden_calf, no_ground_given, Shemot 32:4) says so (tablet 49); with the fact removed, those claims would be calves. Sugya.exceptions_of/2, exception?/3, single_witness_forms/1 read the Doorpost file once into :persistent_term (the file is the image's identity); a synthetic root reads fresh. Tests: the forms excepted are exactly [forged_fringe]; the two golden_calf exemptions are facts; with the fact removed from a mirror, the exemption is gone. Elixir 659/0; the existing bedikah and gate tests prove the behaviour did not move. Doorpost pin unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
133 lines
6.3 KiB
Elixir
133 lines
6.3 KiB
Elixir
defmodule VavPipeline.SugyaTest do
|
|
@moduledoc "The case behind each threshold (specs/sugya.md §IV, step 1): the facts are whole, and the Doorpost refuses a rule without them."
|
|
use ExUnit.Case, async: false
|
|
|
|
alias VavPipeline.{Anchors, Doorpost, Sugya}
|
|
|
|
test "the sugya file is a Doorpost file, beside the anchors" do
|
|
assert "talmudic_engine/src/halt/sugya.pl" in Doorpost.files()
|
|
assert "talmudic_engine/src/halt/anchors.pl" in Doorpost.files()
|
|
end
|
|
|
|
test "every anchored rule has a kind, a precedent and a dissent; every verse is in L1" do
|
|
assert :ok = Sugya.verify()
|
|
{:ok, anchors} = Anchors.declared()
|
|
{:ok, s} = Sugya.declared()
|
|
for a <- anchors do
|
|
assert Enum.any?(s.kinds, &(&1.rule == a.rule)), "#{a.rule} has no kind"
|
|
assert Enum.any?(s.precedents, &(&1.rule == a.rule)), "#{a.rule} has no precedent"
|
|
assert Enum.any?(s.dissents, &(&1.rule == a.rule)), "#{a.rule} has no dissent"
|
|
end
|
|
end
|
|
|
|
test "the kinds follow sugya.md §II: marks seen once, the forms as deeds, the grounding rules as words" do
|
|
{:ok, s} = Sugya.declared()
|
|
kind = fn r -> Enum.find_value(s.kinds, &(&1.rule == r && &1.kind)) end
|
|
assert kind.("lo_taaseh_lekha") == "deed"
|
|
assert kind.("golden_calf") == "word"
|
|
assert kind.("self_grounding") == "word"
|
|
assert kind.("even_vaaven") == "measure"
|
|
for r <- ~w(avodah_zarah shfichut_damim gilui_arayot parah_adumah carrier_centered chelbenah), do: assert(kind.(r) == "mark", r)
|
|
end
|
|
|
|
test "the exception the reader asked to see cited: forged_fringe stands on one witness because it is a mark on the offering" do
|
|
{:ok, s} = Sugya.declared()
|
|
e = Enum.find(s.exceptions, &(&1.rule == "lo_taaseh_lekha" and &1.condition =~ "forged_fringe"))
|
|
assert e, "no single-witness exception for forged_fringe"
|
|
assert Sugya.cite(e.verse) == "Vayikra 22:20"
|
|
# and the two-witness dissent is recorded for every form
|
|
assert Enum.any?(s.dissents, &(&1.rule == "lo_taaseh_lekha" and &1.reading == "single_witness_noted"))
|
|
end
|
|
|
|
test "for_rule/1 renders a rule's sugya for a verdict to carry" do
|
|
r = Sugya.for_rule("golden_calf")
|
|
assert r.kind == "word" and r.verse == "Devarim 18:22"
|
|
assert r.precedent == "tablet(49)"
|
|
assert Enum.any?(r.dissent, &(&1.reading == "hedged"))
|
|
assert Enum.any?(r.exception, &(&1.condition == "no_ground_given"))
|
|
assert Sugya.for_rule("no_such_rule") == nil
|
|
end
|
|
|
|
describe "the code reads its exemptions from the facts (step 2)" do
|
|
test "the single-witness forms are those the sugya excepts, and only those" do
|
|
assert Sugya.single_witness_forms() == ["forged_fringe"]
|
|
end
|
|
|
|
test "the hedged and no-ground exemptions of golden_calf are facts, not constants" do
|
|
assert Sugya.exception?("golden_calf", "hedged")
|
|
assert Sugya.exception?("golden_calf", "no_ground_given")
|
|
refute Sugya.exception?("golden_calf", "anything_at_all")
|
|
refute Sugya.exception?("chelbenah", "hedged")
|
|
end
|
|
|
|
test "with the fact removed, the exemption is gone: behaviour is read from the reason" do
|
|
temp = Path.join(System.tmp_dir!(), "sugya_step2_#{System.unique_integer([:positive])}")
|
|
rel = "talmudic_engine/src/halt/sugya.pl"
|
|
File.mkdir_p!(Path.dirname(Path.join(temp, rel)))
|
|
File.cp!(Path.join(Doorpost.repo_root(), rel), Path.join(temp, rel))
|
|
on_exit(fn -> File.rm_rf!(temp) end)
|
|
assert Sugya.single_witness_forms(temp) == ["forged_fringe"]
|
|
path = Path.join(temp, rel)
|
|
File.write!(path, String.replace(File.read!(path), "exception(lo_taaseh_lekha, single_witness(forged_fringe), verse(vayikra, 22, 20)).", ""))
|
|
assert Sugya.single_witness_forms(temp) == []
|
|
File.write!(path, String.replace(File.read!(path), "exception(golden_calf, hedged, verse(devarim, 18, 22)).", ""))
|
|
refute Sugya.exception?("golden_calf", "hedged", temp)
|
|
end
|
|
end
|
|
|
|
describe "drift (synthetic spec root)" do
|
|
setup do
|
|
temp = Path.join(System.tmp_dir!(), "sugya_test_#{System.unique_integer([:positive])}")
|
|
for rel <- Doorpost.files() do
|
|
src = Path.join(Doorpost.repo_root(), rel)
|
|
dst = Path.join(temp, rel)
|
|
File.mkdir_p!(Path.dirname(dst))
|
|
if File.exists?(src), do: File.cp!(src, dst)
|
|
end
|
|
on_exit(fn -> File.rm_rf!(temp) end)
|
|
%{temp: temp, path: Path.join(temp, "talmudic_engine/src/halt/sugya.pl")}
|
|
end
|
|
|
|
test "a mirror verifies", %{temp: temp} do
|
|
assert :ok = Sugya.verify(temp)
|
|
end
|
|
|
|
test "a rule without a dissent fails: the minority must be recorded", %{temp: temp, path: path} do
|
|
text = File.read!(path) |> String.replace(~r/^dissent\(even_vaaven,.*\n/m, "")
|
|
File.write!(path, text)
|
|
assert {:error, "SUGYA_MISSING: rule even_vaaven has no dissent" <> _} = Sugya.verify(temp)
|
|
end
|
|
|
|
test "a rule without a kind fails", %{temp: temp, path: path} do
|
|
File.write!(path, String.replace(File.read!(path), "kind(chelbenah, mark, verse(vayikra, 13, 3)).", ""))
|
|
assert {:error, "SUGYA_MISSING: rule chelbenah has no kind" <> _} = Sugya.verify(temp)
|
|
end
|
|
|
|
test "a kind that is not one of the four fails", %{temp: temp, path: path} do
|
|
File.write!(path, String.replace(File.read!(path), "kind(chelbenah, mark,", "kind(chelbenah, rumour,"))
|
|
assert {:error, "SUGYA_INVALID: rule chelbenah has kind rumour" <> _} = Sugya.verify(temp)
|
|
end
|
|
|
|
test "a verse that is not in L1 fails", %{temp: temp, path: path} do
|
|
File.write!(path, String.replace(File.read!(path), "verse(vayikra, 22, 20)", "verse(vayikra, 22, 99)"))
|
|
assert {:error, "SUGYA_NOT_IN_L1: Vayikra 22:99" <> _} = Sugya.verify(temp)
|
|
end
|
|
|
|
test "a sugya for a rule that has no anchor fails: nothing added", %{temp: temp, path: path} do
|
|
File.write!(path, File.read!(path) <> "\nexception(new_rule, whatever, verse(bereishit, 1, 1)).\n")
|
|
assert {:error, "SUGYA_INVALID: " <> _ = msg} = Sugya.verify(temp)
|
|
assert msg =~ "new_rule"
|
|
end
|
|
|
|
test "a fact in a comment is not a fact", %{temp: temp, path: path} do
|
|
File.write!(path, File.read!(path) <> "\n%% kind(imaginary, mark, verse(bereishit, 1, 1)).\n")
|
|
assert :ok = Sugya.verify(temp)
|
|
end
|
|
|
|
test "a missing sugya file fails", %{temp: temp, path: path} do
|
|
File.rm!(path)
|
|
assert {:error, "SUGYA_UNREADABLE: " <> _} = Sugya.verify(temp)
|
|
end
|
|
end
|
|
end
|