Packages

The Elixir binding of the Causalontology standard - reified causation as a programming-language-neutral standard and shared commons. OTP stdlib only: RFC 8785 canonicalization, SHA-256 identity, Ed25519 signing, a conformant store. 137 checks: 38 shared vectors, 99 per binding.

Current section

Files

Jump to
causalontology conformance.exs
Raw

conformance.exs

# The Causalontology conformance runner for causalontology-elixir.
#
# Runs every vector in conformance/vectors/ against the Elixir binding. An
# implementation is conformant if and only if it passes every vector; this
# runner exits nonzero on any failure.
#
# Standalone script: it Code.require_file's the lib modules directly, so no
# mix compile is needed — `cd bindings/elixir && elixir conformance.exs`.
#
# The vectors are the whole-word 2.0.0 baseline (Principle P7): V01-V38 are the
# 1.0.0 suite re-frozen unaltered in meaning, V39-V107 are new. They carry
# concrete 64-hex identifiers and real Ed25519 keys, which pass through the
# (retained) normalization unchanged; behavioral vectors derive deterministic
# keypairs from sha256("key:" <> name), exactly as the Python harness does.
Code.require_file("lib/causalontology/json.ex", __DIR__)
Code.require_file("lib/causalontology/jcs.ex", __DIR__)
Code.require_file("lib/causalontology/canonical.ex", __DIR__)
Code.require_file("lib/causalontology/signing.ex", __DIR__)
Code.require_file("lib/causalontology/schema.ex", __DIR__)
Code.require_file("lib/causalontology/semantics.ex", __DIR__)
Code.require_file("lib/causalontology/store.ex", __DIR__)
Code.require_file("lib/causalontology.ex", __DIR__)
defmodule Conformance do
@moduledoc false
alias Causalontology.{Canonical, Jcs, Json, Schema, Semantics, Signing, Store}
# The repository root: CAUSALONTOLOGY_ROOT when set, else two levels up
# from this script (bindings/elixir -> bindings -> root).
@root System.get_env("CAUSALONTOLOGY_ROOT") || Path.expand("../..", __DIR__)
@vecdir Path.join(@root, "conformance/vectors")
# Whole-word schemes (Principle P7); the same set the Python harness uses.
@schemes ~w(occurrent causal_relation_object continuant realizable
assertion enrichment retraction succession
stratum bridge port conduit quality
token_individual token_occurrence state_assertion
token_causal_claim)
@whole_word MapSet.new(@schemes ++ ["ed25519"])
@sym_regex Regex.compile!("^(" <> Enum.join(@schemes ++ ["ed25519"], "|") <> "):")
@hex64 ~r/^[0-9a-f]{64}$/
# -------------------------------------------------------------------------
# symbolic-identifier normalization (frozen concrete values pass through)
# -------------------------------------------------------------------------
# A real, deterministic Ed25519 keypair for a symbolic key name.
defp key(name) do
seed = :crypto.hash(:sha256, "key:" <> name)
Signing.keypair_from_seed(seed)
end
# Normalize one symbolic identifier to a well-formed one.
defp sym(s) do
[scheme, name] = String.split(s, ":", parts: 2)
cond do
scheme == "ed25519" ->
# Frozen: a real key passes through.
if name =~ @hex64, do: s, else: elem(key(name), 1)
name =~ @hex64 ->
s
true ->
scheme <> ":" <> Base.encode16(:crypto.hash(:sha256, name), case: :lower)
end
end
# Recursively normalize symbolic identifiers and placeholders.
defp normalize(x) when is_binary(x) do
cond do
x == "<128 hex>" -> String.duplicate("ab", 64)
x =~ @sym_regex -> sym(x)
true -> x
end
end
defp normalize(x) when is_list(x), do: Enum.map(x, &normalize/1)
defp normalize(x) when is_map(x), do: Map.new(x, fn {k, v} -> {k, normalize(v)} end)
defp normalize(x), do: x
# Load vector n's JSON file (for its structured inputs).
defp vec(n) do
hits = Path.wildcard(Path.join(@vecdir, "v#{pad2(n)}_*.json"))
assert!(length(hits) == 1, "vector #{n} not found")
hits |> hd() |> File.read!() |> Json.parse!()
end
defp vector_name(n) do
case Path.wildcard(Path.join(@vecdir, "v#{pad2(n)}_*.json")) do
[hit] -> Path.basename(hit, ".json")
_ -> "v#{pad2(n)}"
end
end
defp pad2(n), do: n |> Integer.to_string() |> String.pad_leading(2, "0")
defp ts(i), do: "2026-07-13T0#{i}:00:00Z"
# Build, timestamp, and sign a provenance record.
defp signed(kind, body, who, ts_i \\ 0) do
{secret, pub} = key(who)
rec =
body
|> Map.put("type", kind)
|> Map.put_new("timestamp", ts(ts_i))
rec =
if kind == "succession" do
Map.put_new(rec, "predecessor", pub)
else
Map.put(rec, "source", pub)
end
Signing.sign_record(rec, secret, kind)
end
defp assert!(condition, message \\ "assertion failed") do
if condition, do: :ok, else: raise(RuntimeError, message)
end
# -------------------------------------------------------------------------
# content-object builders (mirror bindings/python/tests/run_conformance.py)
# -------------------------------------------------------------------------
# A content object completed with its real content-addressed id.
defp mk(obj), do: Map.put(obj, "id", Canonical.identify(obj))
defp put_if(map, _key, nil), do: map
defp put_if(map, key, value), do: Map.put(map, key, value)
defp stratum(label, scheme, ordinal, unit \\ nil, governs \\ nil) do
mk(
%{"type" => "stratum", "label" => label, "scheme" => scheme, "ordinal" => ordinal}
|> put_if("unit", unit)
|> put_if("governs", governs)
)
end
defp occ(label, stratum_id \\ nil, category \\ "event") do
mk(
%{"type" => "occurrent", "label" => label, "category" => category}
|> put_if("stratum", stratum_id)
)
end
defp cnt(label, category \\ "object"),
do: mk(%{"type" => "continuant", "label" => label, "category" => category})
defp cro(causes, effects, extra \\ %{}) do
mk(Map.merge(%{"type" => "causal_relation_object", "causes" => causes, "effects" => effects}, extra))
end
defp bridge(coarse, fine, relation),
do: mk(%{"type" => "bridge", "coarse" => coarse, "fine" => fine, "relation" => relation})
defp port(bearer, label, direction, accepts, realizable \\ nil) do
mk(
%{
"type" => "port",
"bearer" => bearer,
"label" => label,
"direction" => direction,
"accepts" => accepts
}
|> put_if("realizable", realizable)
)
end
defp conduit(frm, to, carries, transform \\ nil) do
mk(
%{"type" => "conduit", "label" => "conn", "from" => frm, "to" => to, "carries" => carries}
|> put_if("transform", transform)
)
end
defp quality(label, datatype, unit \\ nil, stratum_id \\ nil) do
mk(
%{"type" => "quality", "label" => label, "datatype" => datatype}
|> put_if("unit", unit)
|> put_if("stratum", stratum_id)
)
end
defp individual(instantiates, designator \\ nil, part_of \\ nil) do
mk(
%{"type" => "token_individual", "instantiates" => instantiates}
|> put_if("designator", designator)
|> put_if("part_of", part_of)
)
end
defp token(instantiates, interval, participants \\ nil, locus \\ nil) do
mk(
%{"type" => "token_occurrence", "instantiates" => instantiates, "interval" => interval}
|> put_if("participants", participants)
|> put_if("locus", locus)
)
end
defp state(subject, qual, value, interval),
do:
mk(%{
"type" => "state_assertion",
"subject" => subject,
"quality" => qual,
"value" => value,
"interval" => interval
})
defp tcc(causes, effects, covering_law \\ nil, actual_delay \\ nil, counterfactual \\ nil) do
mk(
%{"type" => "token_causal_claim", "causes" => causes, "effects" => effects}
|> put_if("covering_law", covering_law)
|> put_if("actual_delay", actual_delay)
|> put_if("counterfactual", counterfactual)
)
end
# The neuroendocrine stratum fixture keyed by ordinal.
defp neuro do
labels = %{
4 => "macromolecular",
5 => "subcellular",
6 => "cellular",
7 => "synaptic",
9 => "region",
14 => "community_and_society"
}
Map.new(labels, fn {o, label} -> {o, stratum(label, "neuroendocrine", o)} end)
end
# -------------------------------------------------------------------------
# internal sanity checks (not conformance vectors)
# -------------------------------------------------------------------------
def internal_checks do
# RFC 8032, TEST 1 known-answer.
seed =
Base.decode16!(
"9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60",
case: :lower
)
{pub, _priv} = :crypto.generate_key(:eddsa, :ed25519, seed)
assert!(
Base.encode16(pub, case: :lower) ==
"d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a",
"RFC 8032 TEST 1 public key mismatch: #{Base.encode16(pub, case: :lower)}"
)
sig = :crypto.sign(:eddsa, :none, "", [seed, :ed25519])
assert!(:crypto.verify(:eddsa, :none, "", sig, [pub, :ed25519]), "TEST 1 verify failed")
assert!(not :crypto.verify(:eddsa, :none, "x", sig, [pub, :ed25519]), "verify must reject")
# JCS basics.
assert!(Jcs.encode(%{"b" => 2, "a" => 1}) == ~s({"a":1,"b":2}), "JCS key order wrong")
assert!(Jcs.encode(1.0) == "1", "JCS 1.0 must be 1")
assert!(Jcs.encode(6.000) == "6", "JCS 6.000 must be 6")
assert!(Jcs.encode(0.7) == "0.7", "JCS 0.7 must stay 0.7")
end
# -------------------------------------------------------------------------
# shared vector helpers
# -------------------------------------------------------------------------
defp schema_fails(n, must_mention) do
inp = normalize(vec(n)["input"])
{ok, why} = Schema.validate_schema(inp)
assert!(not ok, "expected schema-invalid")
assert!(
Enum.any?(why, &String.contains?(&1, must_mention)),
"no schema reason mentions #{inspect(must_mention)}: #{inspect(why)}"
)
end
defp semantics_fails(n, must_mention) do
inp = normalize(vec(n)["input"])
{ok, why} = Semantics.validate_semantics(inp)
assert!(not ok, "expected semantically-invalid")
assert!(
Enum.any?(why, &String.contains?(&1, must_mention)),
"no semantic reason mentions #{inspect(must_mention)}: #{inspect(why)}"
)
end
defp adm(n) do
g = vec(n)["given"]
cro = %{
"causes" => [sym("occurrent:c")],
"effects" => [sym("occurrent:e")],
"temporal" => g["temporal"]
}
Semantics.admissible(cro, g["elapsed_seconds"])
end
# -------------------------------------------------------------------------
# V01 - V38: the whole-word re-freeze of the 1.0.0 suite (unaltered meaning)
# -------------------------------------------------------------------------
def run_vector(1) do
inp = normalize(vec(1)["input"])
{ok, why} = Schema.validate_schema(inp)
assert!(ok, inspect(why))
{ok, why} = Semantics.validate_semantics(inp)
assert!(ok, inspect(why))
end
def run_vector(2) do
inp = normalize(vec(2)["input"])
{ok, _} = Schema.validate_schema(inp)
assert!(ok, "schema-invalid")
{ok, _} = Semantics.validate_semantics(inp)
assert!(ok, "semantically-invalid")
{partial, missing} = Semantics.is_partial(inp)
assert!(partial and missing == vec(2)["expect"]["missing"], inspect(missing))
end
def run_vector(3), do: schema_fails(3, "effects")
def run_vector(4), do: schema_fails(4, "causes")
def run_vector(5), do: schema_fails(5, "modality")
def run_vector(6), do: schema_fails(6, "colour")
def run_vector(7), do: schema_fails(7, "causes")
def run_vector(8) do
{ok, why} = Schema.validate_schema(normalize(vec(8)["input"]))
assert!(ok, inspect(why))
end
def run_vector(9), do: schema_fails(9, "label")
def run_vector(10), do: schema_fails(10, "category")
def run_vector(11) do
{ok, why} = Schema.validate_schema(normalize(vec(11)["input"]))
assert!(ok, inspect(why))
end
def run_vector(12), do: schema_fails(12, "confidence")
def run_vector(13) do
inp = normalize(vec(13)["input"])
{ok, why} = Schema.validate_schema(inp)
assert!(ok, inspect(why))
{ok, why} = Semantics.validate_semantics(inp)
assert!(ok, inspect(why))
end
def run_vector(14) do
inp = normalize(vec(14)["input"])
{ok, _} = Schema.validate_schema(inp)
assert!(ok, "schema-invalid")
semantics_fails(14, "minimum_delay")
end
def run_vector(15), do: semantics_fails(15, "acyclic")
def run_vector(16), do: semantics_fails(16, "acyclic")
def run_vector(17) do
v = vec(17)
parent = normalize(v["given"]["parent"])
child = normalize(v["input"])
{ok, reason} = Semantics.refinement_valid(child, parent)
assert!(not ok and String.contains?(reason, "rival"), reason)
end
def run_vector(18), do: semantics_fails(18, "not a legal field")
def run_vector(19), do: semantics_fails(19, "language-tagged")
def run_vector(20) do
dog = sym("continuant:dog")
mam = sym("continuant:mammal")
ani = sym("continuant:animal")
enrich = fn about, entry, i ->
signed("enrichment", %{"about" => about, "field" => "subsumes", "entry" => entry}, "taxo", i)
end
# The enforcing tier rejects the cycle-completing write.
s = Store.new(true)
{:ok, s, _} = Store.put_record(s, enrich.(dog, mam, 1))
{:ok, s, _} = Store.put_record(s, enrich.(mam, ani, 2))
case Store.put_record(s, enrich.(ani, dog, 3)) do
{:ok, _, _} -> raise "enforcing store accepted a cycle"
{:error, _, msg} -> assert!(String.contains?(msg, "cycle"), msg)
end
# Decentralized merge: the view breaks the cycle deterministically.
s2 = Store.new(true)
{:ok, s2, _} = Store.put_record(s2, enrich.(dog, mam, 1))
{:ok, s2, _} = Store.put_record(s2, enrich.(mam, ani, 2))
bad = enrich.(ani, dog, 3)
{:ok, s2, _} = Store.force_merge_record(s2, bad)
{_active, excluded} = Store.active_taxonomy_edges(s2, "subsumes")
assert!(
length(excluded) == 1 and hd(excluded)["id"] == bad["id"],
"cycle not broken deterministically"
)
repair = Store.gaps(s2, "inconsistent_hierarchy")
assert!(Enum.any?(repair, &(&1["id"] == bad["id"])), "no inconsistent_hierarchy gap")
end
def run_vector(21), do: assert!(adm(21) == true, "expected admissible")
def run_vector(22), do: assert!(adm(22) == false, "expected not admissible")
def run_vector(23), do: assert!(adm(23) == true, "fixed unit constants violated")
def run_vector(24) do
v = vec(24)
assert!(
Canonical.identify(normalize(v["inputA"])) == Canonical.identify(normalize(v["inputB"])),
"key order changed the identity"
)
end
def run_vector(25) do
v = vec(25)
assert!(
Canonical.identify(normalize(v["inputA"])) == Canonical.identify(normalize(v["inputB"])),
"number formatting changed the identity"
)
end
def run_vector(26) do
s = Store.new()
obj = %{"type" => "occurrent", "label" => "press_button", "category" => "action"}
{:ok, s, a} = Store.put(s, obj)
{:ok, s, b} = Store.put(s, obj)
assert!(a == b and map_size(s.objects) == 1, "identical put must be idempotent")
end
def run_vector(27) do
s = Store.new()
{:ok, s, occ} =
Store.put(s, %{"type" => "occurrent", "label" => "press_button", "category" => "action"})
entry = %{"lang" => "en", "text" => "press the button"}
r1 = signed("enrichment", %{"about" => occ, "field" => "aliases", "entry" => entry}, "alice", 1)
r2 = signed("enrichment", %{"about" => occ, "field" => "aliases", "entry" => entry}, "bob", 2)
{:ok, s, id1} = Store.put_record(s, r1)
{:ok, s, id2} = Store.put_record(s, r2)
# Two records ...
assert!(id1 != id2, "expected two distinct records")
view = Store.get(s, occ)["enrichments"]["aliases"]
# ... one canonical entry, two contributors.
assert!(length(view) == 1 and length(hd(view)["contributors"]) == 2, "corroboration wrong")
end
def run_vector(28) do
s = Store.new()
claim = %{
"type" => "causal_relation_object",
"causes" => [sym("occurrent:A")],
"effects" => [sym("occurrent:B")],
"modality" => "sufficient"
}
{:ok, s, i1} = Store.put(s, claim)
{:ok, s, i2} = Store.put(s, claim)
assert!(i1 == i2 and map_size(s.objects) == 1, "one claim must stay one object")
s =
Enum.reduce([{"lab1", 1}, {"lab2", 2}], s, fn {who, ts_i}, s ->
record =
signed(
"assertion",
%{"about" => i1, "evidence_type" => "observation", "strength" => 0.8, "confidence" => 0.8},
who,
ts_i
)
{:ok, s, _} = Store.put_record(s, record)
s
end)
assert!(length(Store.assertions_about(s, i1)) == 2, "expected two assertions")
end
def run_vector(29) do
rec =
signed(
"assertion",
%{
"about" => sym("causal_relation_object:demo"),
"evidence_type" => "intervention",
"strength" => 0.7,
"confidence" => 0.9
},
"signer"
)
assert!(Signing.verify_record(rec) == true, "valid signature must verify")
end
def run_vector(30) do
rec =
signed(
"assertion",
%{
"about" => sym("causal_relation_object:demo"),
"evidence_type" => "intervention",
"strength" => 0.7,
"confidence" => 0.9
},
"signer"
)
tampered = Map.put(rec, "confidence", 0.1)
assert!(Signing.verify_record(tampered) == false, "tampered record must fail")
end
def run_vector(31) do
s = Store.new()
{:ok, s, x} =
Store.put(s, %{"type" => "causal_relation_object", "causes" => [sym("occurrent:A")], "effects" => [sym("occurrent:B")]})
a =
signed(
"assertion",
%{"about" => x, "evidence_type" => "observation", "confidence" => 0.8},
"lab1",
1
)
{:ok, s, _} = Store.put_record(s, a)
{:ok, s, _} = Store.put_record(s, signed("retraction", %{"retracts" => a["id"]}, "lab1", 2))
assert!(Store.assertions_about(s, x) == [], "retracted assertion still in default view")
hist = Store.assertions_about(s, x, true)
assert!(length(hist) == 1 and hd(hist)["retracted"] == true, "history flag wrong")
foreign = signed("retraction", %{"retracts" => a["id"]}, "mallory", 3)
case Store.put_record(s, foreign) do
{:ok, _, _} ->
raise "foreign retraction accepted"
{:error, s, _msg} ->
# Still excluded by lab1's own retraction.
assert!(Store.assertions_about(s, x) == [], "default view changed")
assert!(length(Store.assertions_about(s, x, true)) == 1, "history changed")
end
end
def run_vector(32) do
s = Store.new()
{:ok, s, occ} =
Store.put(s, %{"type" => "occurrent", "label" => "press_button", "category" => "action"})
e =
signed(
"enrichment",
%{"about" => occ, "field" => "aliases", "entry" => %{"lang" => "ja", "text" => "botan"}},
"bob",
1
)
{:ok, s, _} = Store.put_record(s, e)
aliases = Map.get(Store.get(s, occ)["enrichments"], "aliases", [])
assert!(length(aliases) == 1, "enrichment not visible before retraction")
{:ok, s, _} = Store.put_record(s, signed("retraction", %{"retracts" => e["id"]}, "bob", 2))
assert!(Map.get(Store.get(s, occ)["enrichments"], "aliases", []) == [], "not retracted")
hist = Map.get(Store.get(s, occ, "history")["enrichments"], "aliases", [])
assert!(length(hist) == 1, "history must keep the retracted enrichment")
end
def run_vector(33) do
s = Store.new()
{_, k1} = key("K1")
{_, k2} = key("K2")
a =
signed(
"assertion",
%{"about" => sym("causal_relation_object:claim"), "evidence_type" => "observation", "confidence" => 0.9},
"K1",
1
)
{:ok, s, _} = Store.put_record(s, a)
succ = signed("succession", %{"successor" => k2}, "K1", 2)
{:ok, s, _} = Store.put_record(s, succ)
assert!(
MapSet.member?(Store.lineage(s, k2), k1) and MapSet.member?(Store.lineage(s, k1), k2),
"lineage closure wrong"
)
# The successor may retract the predecessor's record.
r = signed("retraction", %{"retracts" => a["id"]}, "K2", 3)
{:ok, s, _} = Store.put_record(s, r)
assert!(Store.assertions_about(s, sym("causal_relation_object:claim")) == [], "succession lineage not honored")
end
def run_vector(34) do
g = normalize(vec(34)["given"])
assert!(Semantics.conflicts(g["A"], g["B"]) == true, "expected a conflict")
end
def run_vector(35) do
g = normalize(vec(35)["given"])
assert!(Semantics.conflicts(g["A"], g["B"]) == false, "expected no conflict")
end
def run_vector(36) do
a = sym("occurrent:A")
b = sym("occurrent:B")
c = sym("occurrent:C")
d = sym("occurrent:D")
m1 = %{"id" => sym("causal_relation_object:m1"), "causes" => [a], "effects" => [b]}
m2 = %{"id" => sym("causal_relation_object:m2"), "causes" => [b], "effects" => [c]}
m3 = %{"id" => sym("causal_relation_object:m3"), "causes" => [d], "effects" => [c]}
p = %{"causes" => [a], "effects" => [c], "mechanism" => [m1["id"], m2["id"]]}
assert!(
Semantics.hierarchy_consistent(p, %{m1["id"] => m1, m2["id"] => m2}) == "consistent",
"expected consistent"
)
p2 = Map.put(p, "mechanism", [m1["id"], m3["id"]])
assert!(
Semantics.hierarchy_consistent(p2, %{m1["id"] => m1, m3["id"] => m3}) == "inconsistent",
"expected inconsistent"
)
assert!(
Semantics.hierarchy_consistent(p, %{m1["id"] => m1}) == "indeterminate",
"expected indeterminate"
)
end
def run_vector(37) do
s = Store.new()
{:ok, s, occ} =
Store.put(s, %{"type" => "occurrent", "label" => "press_button", "category" => "action"})
record =
signed(
"enrichment",
%{
"about" => occ,
"field" => "aliases",
"entry" => %{"lang" => "en", "text" => "Press the Button"}
},
"alice",
1
)
{:ok, s, _} = Store.put_record(s, record)
# Alias match, with whitespace and case normalized away.
assert!(Store.resolve(s, "Press The Button", "en") == [occ], "alias resolve failed")
# Exact label match ranks first.
assert!(hd(Store.resolve(s, "press_button", "en")) == occ, "label resolve failed")
end
def run_vector(38) do
s = Store.new()
{:ok, s, p} =
Store.put(s, %{"type" => "causal_relation_object", "causes" => [sym("occurrent:A")], "effects" => [sym("occurrent:B")]})
gap_ids = Enum.map(Store.gaps(s, "missing_field"), & &1["id"])
assert!(p in gap_ids, "the degenerate claim must be a visible gap")
{:ok, s, r} =
Store.put(s, %{
"type" => "causal_relation_object",
"causes" => [sym("occurrent:A")],
"effects" => [sym("occurrent:B")],
"temporal" => %{"minimum_delay" => 0, "maximum_delay" => 1, "unit" => "seconds"},
"modality" => "sufficient",
"refines" => p
})
gap_ids = Enum.map(Store.gaps(s, "missing_field"), & &1["id"])
assert!(p not in gap_ids, "the gap did not close")
assert!(r not in gap_ids, "the refinement itself must be complete")
end
# -------------------------------------------------------------------------
# V39 - V107: the 2.0.0 additions
# -------------------------------------------------------------------------
def run_vector(39) do
st = stratum("cellular", "neuroendocrine", 6, "cell", ["cell_biology"])
{ok, why} = Schema.validate_schema(st)
assert!(ok, inspect(why))
end
def run_vector(40) do
bad = mk(%{"type" => "stratum", "label" => "cellular", "ordinal" => 6})
{ok, why} = Schema.validate_schema(bad, "stratum")
assert!(not ok and Enum.any?(why, &String.contains?(&1, "scheme")), inspect(why))
end
def run_vector(41) do
a = stratum("cellular", "neuroendocrine", 6)
b = stratum("neuronal", "neuroendocrine", 6)
for x <- [a, b] do
{ok, why} = Schema.validate_schema(x)
assert!(ok, inspect(why))
end
assert!(a["id"] != b["id"], "same-ordinal strata must be distinct")
end
def run_vector(42) do
s = neuro()
s4p = stratum("molecular", "physics", 4)
c = occ("chronic_social_subordination", s[14]["id"])
e = occ("gene_expression", s4p["id"])
smap = %{s[14]["id"] => s[14], s4p["id"] => s4p}
omap = %{c["id"] => c, e["id"] => e}
p = cro([c["id"]], [e["id"]])
assert!(Semantics.classify_cro(p, omap, smap) == "scheme_mismatch", "expected scheme_mismatch")
end
def run_vector(43) do
for x <- [stratum("macromolecular", "neuroendocrine", 4), stratum("region", "neuroendocrine", 9)] do
{ok, why} = Schema.validate_schema(x)
assert!(ok, inspect(why))
end
end
def run_vector(44) do
st = stratum("cellular", "neuroendocrine", 6)
o = occ("neuron_fires", st["id"])
{ok, why} = Schema.validate_schema(o)
assert!(ok, inspect(why))
{ok, why} = Semantics.validate_semantics(o)
assert!(ok, inspect(why))
end
def run_vector(45) do
o = occ("press_button")
{ok, why} = Schema.validate_schema(o)
assert!(ok, inspect(why))
e = occ("light_on")
p = cro([o["id"]], [e["id"]])
assert!(Semantics.classify_cro(p, %{o["id"] => o, e["id"] => e}, %{}) == "unclassifiable", "expected unclassifiable")
end
def run_vector(46) do
s = neuro()
a = occ("depolarization", s[5]["id"])
b = occ("depolarization", s[6]["id"])
assert!(a["id"] != b["id"], "same label, different stratum must be distinct")
end
def run_vector(47), do: valid_bridge("constitutes")
def run_vector(48), do: valid_bridge("aggregates")
def run_vector(49), do: valid_bridge("realizes")
def run_vector(50), do: valid_bridge("supervenes_on")
def run_vector(51) do
s = neuro()
coarse = occ("x_coarse", s[4]["id"])
fine = occ("x_fine", s[6]["id"])
b = bridge(coarse["id"], [fine["id"]], "constitutes")
omap = %{coarse["id"] => coarse, fine["id"] => fine}
smap = %{s[4]["id"] => s[4], s[6]["id"] => s[6]}
{ok, _} = Semantics.bridge_wellformed(b, omap, smap)
assert!(not ok, "coarse ordinal not > fine must be malformed")
end
def run_vector(52) do
s = neuro()
coarse = occ("c", s[6]["id"])
f1 = occ("f1", s[4]["id"])
f2 = occ("f2", s[5]["id"])
b = bridge(coarse["id"], [f1["id"], f2["id"]], "constitutes")
omap = %{coarse["id"] => coarse, f1["id"] => f1, f2["id"] => f2}
smap = %{s[4]["id"] => s[4], s[5]["id"] => s[5], s[6]["id"] => s[6]}
{ok, _} = Semantics.bridge_wellformed(b, omap, smap)
assert!(not ok, "fine spanning >1 stratum must be malformed")
end
def run_vector(53) do
x = sym("occurrent:x")
y = sym("occurrent:y")
b1 = bridge(x, [y], "constitutes")
b2 = bridge(y, [x], "constitutes")
edges =
Enum.reduce([b1, b2], %{}, fn b, acc ->
Enum.reduce(b["fine"], acc, fn f, a ->
Map.update(a, f, [b["coarse"]], &(&1 ++ [b["coarse"]]))
end)
end)
assert!(Semantics.has_cycle(edges) == true, "expected a cycle")
end
def run_vector(54) do
a = stratum("cellular", "neuroendocrine", 6)
b = stratum("molecular", "physics", 4)
coarse = occ("c", a["id"])
fine = occ("f", b["id"])
br = bridge(coarse["id"], [fine["id"]], "constitutes")
omap = %{coarse["id"] => coarse, fine["id"] => fine}
smap = %{a["id"] => a, b["id"] => b}
{ok, _} = Semantics.bridge_wellformed(br, omap, smap)
assert!(not ok, "cross-scheme bridge must be malformed")
end
def run_vector(55) do
s = neuro()
coarse = occ("decision_made", s[6]["id"])
f1 = occ("cascade_a", s[4]["id"])
f2 = occ("cascade_b", s[4]["id"])
b1 = bridge(coarse["id"], [f1["id"]], "realizes")
b2 = bridge(coarse["id"], [f2["id"]], "realizes")
assert!(b1["id"] != b2["id"], "distinct realizations must differ")
for b <- [b1, b2] do
{ok, why} = Schema.validate_schema(b)
assert!(ok, inspect(why))
end
end
def run_vector(56) do
{p, members, bridges} = reach_fixture()
assert!(Semantics.hierarchy_consistent(p, members, bridges) == "consistent", "expected consistent")
end
def run_vector(57) do
{p, members, _} = reach_fixture()
assert!(Semantics.hierarchy_consistent(p, members, []) == "inconsistent", "expected inconsistent")
end
def run_vector(58) do
{p, members, bridges} = reach_fixture()
literal = Semantics.hierarchy_consistent(p, members, [])
bridged = Semantics.hierarchy_consistent(p, members, bridges)
assert!(literal != "consistent" and bridged == "consistent", "literal=#{literal} bridged=#{bridged}")
end
def run_vector(59), do: assert!(classify(6, 6) == "intra_stratal", "expected intra_stratal")
def run_vector(60), do: assert!(classify(6, 5) == "adjacent_stratal", "expected adjacent_stratal")
def run_vector(61), do: assert!(classify(14, 4) == "skipping", "expected skipping")
def run_vector(62) do
{p, cls} = skip_fixture(14, 4)
assert!(Semantics.skip_gaps(p, cls) == ["incomplete_mechanism"], "expected [incomplete_mechanism]")
end
def run_vector(63) do
{p, cls} = skip_fixture(14, 4, %{"skips" => true})
assert!(Semantics.skip_gaps(p, cls) == [], "expected []")
end
def run_vector(64) do
{p, cls} = skip_fixture(14, 4, %{"skips" => true, "mechanism" => [sym("causal_relation_object:m")]})
assert!(Semantics.skip_gaps(p, cls) == ["contradictory_skip"], "expected [contradictory_skip]")
{ok, why} = Semantics.validate_semantics(p)
assert!(not ok and Enum.any?(why, &String.contains?(&1, "contradictory_skip")), inspect(why))
end
def run_vector(65) do
{p, cls} = skip_fixture(6, 6, %{"skips" => true})
assert!(Semantics.skip_gaps(p, cls) == ["vacuous_skip"], "expected [vacuous_skip]")
end
def run_vector(66) do
s = neuro()
c = occ("c", s[14]["id"])
e = occ("e", s[4]["id"])
absent = cro([c["id"]], [e["id"]])
false_ = cro([c["id"]], [e["id"]], %{"skips" => false})
assert!(absent["id"] != false_["id"], "absent skips vs skips:false must differ")
end
def run_vector(67) do
s = neuro()
c1 = occ("c1", s[4]["id"])
c2 = occ("c2", s[6]["id"])
e = occ("e", s[6]["id"])
p = cro([c1["id"], c2["id"]], [e["id"]])
assert!(Semantics.endpoints_mixed(p, %{c1["id"] => c1, c2["id"] => c2, e["id"] => e}) == true, "expected mixed endpoints")
end
def run_vector(68) do
p = cro([sym("occurrent:a")], [sym("occurrent:b")], %{"modality" => "enabling"})
{ok, why} = Schema.validate_schema(p)
assert!(ok, inspect(why))
end
def run_vector(69) do
a = %{"causes" => [sym("occurrent:a")], "effects" => [sym("occurrent:b")], "modality" => "enabling"}
b = %{"causes" => [sym("occurrent:a")], "effects" => [sym("occurrent:b")], "modality" => "sufficient"}
assert!(Semantics.conflicts(a, b) == false, "enabling vs sufficient must not conflict")
end
def run_vector(70) do
a = %{"causes" => [sym("occurrent:a")], "effects" => [sym("occurrent:b")], "modality" => "enabling"}
b = %{"causes" => [sym("occurrent:a")], "effects" => [sym("occurrent:b")], "modality" => "preventive"}
assert!(Semantics.conflicts(a, b) == true, "enabling vs preventive must conflict")
end
def run_vector(71) do
b = cnt("hippocampus")
p = port(b["id"], "perforant_path", "in", [sym("occurrent:signal")])
{ok, why} = Schema.validate_schema(p)
assert!(ok, inspect(why))
end
def run_vector(72) do
b = cnt("hippocampus")["id"]
x = sym("occurrent:signal")
assert!(port(b, "perforant_path", "in", [x])["id"] != port(b, "fornix", "in", [x])["id"], "ports must differ by label")
end
def run_vector(73) do
{c, pmap, _} = conduit_fixture()
{ok, why} = Schema.validate_schema(c)
assert!(ok, inspect(why))
{ok, why} = Semantics.conduit_wellformed(c, pmap)
assert!(ok, inspect(why))
end
def run_vector(74) do
{c, pmap, cmap} = conduit_fixture(transform: true)
{ok, why} = Schema.validate_schema(c)
assert!(ok, inspect(why))
{ok, why} = Semantics.conduit_wellformed(c, pmap, cmap)
assert!(ok, inspect(why))
end
def run_vector(75) do
{c, pmap, _} = conduit_fixture(bad_carry: true)
{ok, _} = Semantics.conduit_wellformed(c, pmap)
assert!(not ok, "carries not accepted by from must be malformed")
end
def run_vector(76) do
{c, pmap, _} = conduit_fixture(in_from: true)
{ok, _} = Semantics.conduit_wellformed(c, pmap)
assert!(not ok, "from port not out/bidirectional must be malformed")
end
def run_vector(77) do
{c, pmap, cmap} = conduit_fixture(transform: true)
{ok, why} = Semantics.conduit_wellformed(c, pmap, cmap)
assert!(ok, inspect(why))
law = cmap |> Map.values() |> hd()
assert!(hd(law["effects"]) not in c["carries"], "transform output must not be carried directly")
end
def run_vector(78) do
b = cnt("hippocampus")["id"]
assert!(rlz(b, "disposition", "long_term_potentiation")["id"] != rlz(b, "disposition", "pattern_separation")["id"], "labels must distinguish realizables")
end
def run_vector(79) do
b = cnt("hippocampus")["id"]
u1 = rlz(b, "disposition")
u2 = rlz(b, "disposition")
{ok, why} = Schema.validate_schema(u1)
assert!(ok, inspect(why))
assert!(u1["id"] == u2["id"], "unlabeled realizables must be identical")
assert!(rlz(b, "disposition", "some_function")["id"] != u1["id"], "label must change identity")
end
def run_vector(80) do
parent = occ("fires")
child = occ("fires_action_potential")
e = %{"type" => "enrichment", "about" => child["id"], "field" => "occurrent_subsumes", "entry" => parent["id"]}
{ok, why} = Semantics.validate_semantics(e)
assert!(ok, inspect(why))
end
def run_vector(81) do
a = sym("occurrent:a")
b = sym("occurrent:b")
assert!(Semantics.has_cycle(%{a => [b], b => [a]}) == true, "expected a cycle")
end
def run_vector(82) do
whole = occ("eat")
part = occ("chew")
e = %{"type" => "enrichment", "about" => part["id"], "field" => "occurrent_part_of", "entry" => whole["id"]}
{ok, why} = Semantics.validate_semantics(e)
assert!(ok, inspect(why))
end
def run_vector(83) do
{legal_kinds, shape} = Map.fetch!(Semantics.enrichment_fields(), "occurrent_part_of")
assert!(shape == "occurrent" and legal_kinds == ["occurrent"], "occurrent_part_of spec wrong")
s = Store.new()
{:ok, s, _} = Store.put(s, occ("eat"))
{:ok, s, _} = Store.put(s, occ("chew"))
assert!(
not Enum.any?(Map.values(s.objects), &(Map.get(&1, "type") == "causal_relation_object")),
"no CRO must sneak into the store"
)
end
def run_vector(84) do
s = neuro()
a = occ("run", s[9]["id"])
b = occ("sprint", s[6]["id"])
assert!(a["stratum"] != b["stratum"], "different strata must differ")
end
def run_vector(85) do
c = cnt("human_patient")
ti = individual(c["id"], "salted_hash_abc123")
{ok, why} = Schema.validate_schema(ti)
assert!(ok, inspect(why))
end
def run_vector(86) do
bad = mk(%{"type" => "token_individual", "designator" => "x"})
{ok, why} = Schema.validate_schema(bad, "token_individual")
assert!(not ok and Enum.any?(why, &String.contains?(&1, "instantiates")), inspect(why))
end
def run_vector(87) do
c = cnt("human_patient")["id"]
assert!(individual(c, "hash_a")["id"] != individual(c, "hash_b")["id"], "designator must distinguish individuals")
end
def run_vector(88) do
o = occ("bilateral_hippocampal_resection")
t = token(o["id"], %{"start" => "1953-08-25T00:00:00Z", "end" => "1953-08-25T00:00:00Z"})
{ok, why} = Schema.validate_schema(t)
assert!(ok, inspect(why))
end
def run_vector(89) do
o = occ("amnesia_onset")["id"]
bounded = token(o, %{"start" => "1953-08-25T00:00:00Z", "end" => "1953-08-26T00:00:00Z"})
instantaneous = token(o, %{"start" => "1953-08-25T00:00:00Z"})
ongoing = token(o, %{"start" => "1953-08-25T00:00:00Z", "open" => true})
assert!(MapSet.size(MapSet.new([bounded["id"], instantaneous["id"], ongoing["id"]])) == 3, "three interval shapes must differ")
end
def run_vector(90) do
o = occ("resection")["id"]
c = cnt("human_patient")["id"]
patient = individual(c, "p")["id"]
surgeon = individual(c, "s")["id"]
t =
token(o, %{"start" => "1953-08-25T00:00:00Z"}, [
%{"role" => "patient", "filler" => patient},
%{"role" => "agent", "filler" => surgeon}
])
{ok, why} = Schema.validate_schema(t)
assert!(ok, inspect(why))
end
def run_vector(91) do
q = quality("cortisol_concentration", "quantity", "ug/dL")
{ok, why} = Schema.validate_schema(q)
assert!(ok, inspect(why))
end
def run_vector(92) do
{st, q} = state_fixture("quantity", %{"quantity" => 15.0, "unit" => "ug/dL"}, "ug/dL")
{ok, why} = Schema.validate_schema(st)
assert!(ok, inspect(why))
assert!(Semantics.state_gaps(st, q) == [], "expected no gaps")
end
def run_vector(93) do
{st, q} = state_fixture("categorical", %{"categorical" => "elevated"})
{ok, why} = Schema.validate_schema(st)
assert!(ok, inspect(why))
assert!(Semantics.state_gaps(st, q) == [], "expected no gaps")
end
def run_vector(94) do
{st, q} = state_fixture("boolean", %{"boolean" => true})
{ok, why} = Schema.validate_schema(st)
assert!(ok, inspect(why))
assert!(Semantics.state_gaps(st, q) == [], "expected no gaps")
end
def run_vector(95) do
{st, q} = state_fixture("quantity", %{"categorical" => "elevated"}, "ug/dL")
assert!(Semantics.state_gaps(st, q) == ["value_type_mismatch"], "expected [value_type_mismatch]")
end
def run_vector(96) do
{st, q} = state_fixture("quantity", %{"quantity" => 15.0, "unit" => "mg/dL"}, "ug/dL")
assert!(Semantics.state_gaps(st, q) == ["unit_mismatch"], "expected [unit_mismatch]")
end
def run_vector(97) do
{law, _, _, tc, te} = law_and_tokens()
claim =
tcc([tc["id"]], [te["id"]], law["id"], %{"duration" => 0, "unit" => "instant"}, true)
{ok, why} = Schema.validate_schema(claim)
assert!(ok, inspect(why))
end
def run_vector(98) do
{_, _, _, tc, te} = law_and_tokens()
claim = tcc([tc["id"]], [te["id"]])
{ok, why} = Schema.validate_schema(claim)
assert!(ok, inspect(why))
assert!(not Map.has_key?(claim, "covering_law"), "covering_law must be absent")
end
def run_vector(99) do
{law, _, _, _, _} = law_and_tokens()
assert!(Semantics.delay_within_window(%{"duration" => 0, "unit" => "instant"}, law["temporal"]) == true, "instant must be within window")
end
def run_vector(100) do
temporal = %{"minimum_delay" => 0, "maximum_delay" => 1, "unit" => "hours"}
assert!(Semantics.delay_within_window(%{"duration" => 5, "unit" => "days"}, temporal) == false, "5 days must be outside a 1-hour window")
end
def run_vector(101) do
o = occ("x")["id"]
cause = token(o, %{"start" => "2026-01-02T00:00:00Z"})
effect = token(o, %{"start" => "2026-01-01T00:00:00Z"})
claim = tcc([cause["id"]], [effect["id"]])
assert!(Semantics.retrocausal(claim, %{cause["id"] => cause, effect["id"] => effect}) == true, "expected retrocausal")
end
def run_vector(102) do
other = cro([sym("occurrent:foo")], [sym("occurrent:bar")])
{_, _, _, tc, te} = law_and_tokens()
claim = tcc([tc["id"]], [te["id"]], other["id"])
assert!(Semantics.covering_law_mismatch(claim, %{tc["id"] => tc, te["id"] => te}, other) == true, "expected covering-law mismatch")
end
def run_vector(103) do
a =
signed(
"assertion",
%{"about" => sym("token_occurrence:t"), "evidence_type" => "observation", "confidence" => 0.9},
"signer"
)
{ok, why} = Schema.validate_schema(a)
assert!(ok, inspect(why))
end
def run_vector(104) do
ev = [sym("token_occurrence:t1"), sym("token_causal_claim:c1")]
base = %{
"type" => "assertion",
"about" => sym("causal_relation_object:law"),
"source" => elem(key("signer"), 1),
"evidence_type" => "intervention",
"strength" => 0.95,
"confidence" => 0.99,
"timestamp" => "2026-07-14T00:00:00Z"
}
a = Map.put(base, "evidenced_by", ev)
{ok, why} = Schema.validate_schema(Map.put(a, "id", Canonical.identify(a)))
assert!(ok, inspect(why))
assert!(Canonical.identify(a) != Canonical.identify(base), "evidenced_by must be identity-bearing")
end
def run_vector(105) do
a =
signed(
"assertion",
%{"about" => sym("causal_relation_object:law"), "evidence_type" => "simulation", "confidence" => 0.5},
"signer"
)
{ok, why} = Schema.validate_schema(a)
assert!(ok, inspect(why))
rank = %{"intervention" => 0, "observation" => 1, "simulation" => 2}
assert!(rank["intervention"] < rank["observation"] and rank["observation"] < rank["simulation"], "evidence rank order wrong")
end
def run_vector(106) do
id_re = ~r/^([a-z0-9_]+):[0-9a-f]{64}$/
for n <- 1..38 do
ids = scan_schemes(vec(n), id_re, [])
for scheme <- ids do
assert!(MapSet.member?(@whole_word, scheme), "V106: abbreviated scheme #{inspect(scheme)} in vector #{n}")
end
end
rec = %{"type" => "occurrent", "label" => "press_button", "category" => "action"}
assert!(Canonical.identify(rec) == Canonical.identify(rec), "identity must be deterministic")
assert!(Canonical.identify(rec) |> String.split(":", parts: 2) |> hd() == "occurrent", "whole-word prefix expected")
end
def run_vector(107) do
hexid = String.duplicate("0", 64)
# NOTE: the abbreviated prefix below is INTENTIONAL (the negative test); it
# must NOT be re-minted. "c" "r" "o" is assembled to survive re-mint tools.
cro_abbr = "c" <> "r" <> "o"
abbreviated = %{
"type" => "causal_relation_object",
"id" => cro_abbr <> ":" <> hexid,
"causes" => ["occurrent:" <> hexid],
"effects" => ["occurrent:" <> hexid]
}
{ok, _} = Schema.validate_schema(abbreviated, "causal_relation_object")
assert!(not ok, "abbreviated scheme must be rejected")
abbr_str = %{
"type" => "stratum",
"id" => "str" <> ":" <> hexid,
"label" => "cellular",
"scheme" => "neuroendocrine",
"ordinal" => 6
}
{ok, _} = Schema.validate_schema(abbr_str, "stratum")
assert!(not ok, "abbreviated stratum scheme must be rejected")
whole = %{
"type" => "causal_relation_object",
"id" => "causal_relation_object:" <> hexid,
"causes" => ["occurrent:" <> hexid],
"effects" => ["occurrent:" <> hexid]
}
{ok, why} = Schema.validate_schema(whole, "causal_relation_object")
assert!(ok, inspect(why))
end
# -------------------------------------------------------------------------
# fixtures shared by the 2.0.0 vectors (grouped here so the run_vector/1
# clauses stay contiguous)
# -------------------------------------------------------------------------
defp bridge_fixture(relation) do
s = neuro()
coarse = occ("action_potential_fires", s[6]["id"])
fine = [occ("sodium_channels_open", s[4]["id"]), occ("sodium_influx", s[4]["id"])]
b = bridge(coarse["id"], Enum.map(fine, & &1["id"]), relation)
omap = Enum.reduce(fine, %{coarse["id"] => coarse}, fn f, acc -> Map.put(acc, f["id"], f) end)
smap = %{s[4]["id"] => s[4], s[6]["id"] => s[6]}
{b, omap, smap}
end
defp valid_bridge(relation) do
{b, omap, smap} = bridge_fixture(relation)
{ok, why} = Schema.validate_schema(b)
assert!(ok, inspect(why))
{ok, why} = Semantics.bridge_wellformed(b, omap, smap)
assert!(ok, inspect(why))
end
defp reach_fixture do
s = neuro()
ap = occ("action_potential_fires", s[6]["id"])
nt = occ("neurotransmitter_released", s[6]["id"])
fa = occ("calcium_enters", s[4]["id"])
fb = occ("vesicle_fuses", s[4]["id"])
m1 = cro([fa["id"]], [fb["id"]])
p = cro([ap["id"]], [nt["id"]], %{"mechanism" => [m1["id"]]})
bridges = [bridge(ap["id"], [fa["id"]], "constitutes"), bridge(nt["id"], [fb["id"]], "constitutes")]
{p, %{m1["id"] => m1}, bridges}
end
defp classify(cause_ord, effect_ord) do
s = neuro()
c = occ("c", s[cause_ord]["id"])
e = occ("e", s[effect_ord]["id"])
smap = %{s[cause_ord]["id"] => s[cause_ord], s[effect_ord]["id"] => s[effect_ord]}
omap = %{c["id"] => c, e["id"] => e}
Semantics.classify_cro(cro([c["id"]], [e["id"]]), omap, smap)
end
defp skip_fixture(cause_ord, effect_ord, extra \\ %{}) do
s = neuro()
c = occ("c", s[cause_ord]["id"])
e = occ("e", s[effect_ord]["id"])
smap = %{s[cause_ord]["id"] => s[cause_ord], s[effect_ord]["id"] => s[effect_ord]}
omap = %{c["id"] => c, e["id"] => e}
p = cro([c["id"]], [e["id"]], extra)
{p, Semantics.classify_cro(p, omap, smap)}
end
defp conduit_fixture(opts \\ []) do
transform = Keyword.get(opts, :transform, false)
bad_carry = Keyword.get(opts, :bad_carry, false)
in_from = Keyword.get(opts, :in_from, false)
x = sym("occurrent:motor_command")
y = sym("occurrent:error_signal")
z = sym("occurrent:unrelated")
m1 = cnt("motor_cortex")["id"]
m2 = cnt("spinal_neuron")["id"]
frm = port(m1, "out_port", if(in_from, do: "in", else: "out"), [x])
to = port(m2, "in_port", "in", if(transform, do: [y], else: [x]))
carries = if bad_carry, do: [z], else: [x]
{xform, cro_map} =
if transform do
law = cro([x], [y])
{law["id"], %{law["id"] => law}}
else
{nil, %{}}
end
c = conduit(frm["id"], to["id"], carries, xform)
{c, %{frm["id"] => frm, to["id"] => to}, cro_map}
end
defp rlz(bearer, kind, label \\ nil) do
mk(
%{"type" => "realizable", "kind" => kind, "bearer" => bearer}
|> put_if("label", label)
)
end
defp state_fixture(datatype, value, unit \\ nil) do
q = quality("cortisol_concentration", datatype, unit)
c = cnt("human_patient")["id"]
subj = individual(c, "p")["id"]
st = state(subj, q["id"], value, %{"start" => "2026-01-01T00:00:00Z", "end" => "2026-01-01T01:00:00Z"})
{st, q}
end
defp law_and_tokens do
o_cause = occ("resection")
o_effect = occ("amnesia_onset")
law =
cro([o_cause["id"]], [o_effect["id"]], %{
"temporal" => %{"minimum_delay" => 0, "maximum_delay" => 1, "unit" => "days"},
"modality" => "sufficient"
})
t_cause = token(o_cause["id"], %{"start" => "1953-08-25T00:00:00Z"})
t_effect = token(o_effect["id"], %{"start" => "1953-08-25T00:00:00Z", "open" => true})
{law, o_cause, o_effect, t_cause, t_effect}
end
defp scan_schemes(node, re, acc) when is_binary(node) do
case Regex.run(re, node) do
[_, scheme] -> [scheme | acc]
nil -> acc
end
end
defp scan_schemes(node, re, acc) when is_list(node),
do: Enum.reduce(node, acc, fn x, a -> scan_schemes(x, re, a) end)
defp scan_schemes(node, re, acc) when is_map(node),
do: Enum.reduce(Map.values(node), acc, fn x, a -> scan_schemes(x, re, a) end)
defp scan_schemes(_node, _re, acc), do: acc
# -------------------------------------------------------------------------
def main do
IO.puts("causalontology-elixir conformance run")
IO.write("internal checks (RFC 8032 known-answer, RFC 8785 basics) ... ")
internal_checks()
IO.puts("ok")
failures =
Enum.reduce(1..107, 0, fn n, failures ->
name = vector_name(n)
try do
run_vector(n)
IO.puts("PASS #{name}")
failures
rescue
e ->
IO.puts("FAIL #{name} :: #{Exception.message(e)}")
failures + 1
catch
kind, value ->
IO.puts("FAIL #{name} :: #{inspect({kind, value})}")
failures + 1
end
end)
total = 107
IO.puts(String.duplicate("-", 60))
IO.puts("#{total - failures}/#{total} vectors passed")
if failures > 0 do
System.halt(1)
end
IO.puts(
"causalontology-elixir is CONFORMANT to the suite " <>
"(vectors frozen at specification 2.0.0)."
)
end
end
Conformance.main()