Argument map
An argument kept as a record, and the shape that needed path patterns.
Three kinds of document. A claim states something. An inference
draws one claim from others: its premises name the claims it starts from,
and concludes names the claim it reaches. An objection challenges a
claim or an inference.
No field says which claim follows from which. That fact takes two
fields on two documents: premise_of on the premise and concludes on the
inference. A chain over either field alone stops at the inference. So the
line is declared as a named path pattern, and the chain walks that:
patterns:
follows_from: (b:CLAIM)<-[:concludes]-(i:INF)<-[:premise_of]-(a:CLAIM)It reads like the field it stands in for: the first node is the step and
the last is the claim it builds on, so a conclusion nests under its
premises. i is named, so each step on the page says which inference it
went through.
Two views of one argument. Lines of argument walks
every step. Uncontested lines walks stands_on, the
same pattern with WHERE NOT (i)<-[:challenges]-(:OBJ). It drops the step
from the 2025 inspection to “the repair can wait”, because OBJ-001
challenges it.
An unfinished step is a page of its own. INF-004 has a premise and no
conclusion yet, so it is not a step on either chain. What counts as
unfinished depends on what this record requires, so luria does not guess;
the record says it as a pattern, and gives the pattern an output:
unfinished:
match: (i:INF)<-[:premise_of]-(p:CLAIM) WHERE NOT (i)-[:concludes]->(:CLAIM)
output: docs/unfinished.mdUnfinished steps lists each match as an outline:
the inference, and under it the premise it has. A page nests its matches by
shared prefix, the way a chain nests its steps; layout: table gives one
row per match instead.
Two patterns can share a page. A step and the objection to it are a
pattern and a longer one, and naming one output for both merges their
matches into one outline:
steps:
match: (b:CLAIM)<-[:concludes]-(i:INF)
output: docs/disputes.md
disputed:
match: (b:CLAIM)<-[:concludes]-(i:INF)<-[:challenges]-(o:OBJ)
output: docs/disputes.mdSteps and their objections puts every inference under the claim it concludes, and OBJ-001 under the one step it challenges. The other steps are there too, with nothing under them: the shorter pattern matched them, and the longer one only adds what it finds.
LURIA_ROOT=$PWD luria index
LURIA_ROOT=$PWD luria lint