The setup
"How do I write this requirement as a check the tool can prove?"
"This check came back Falsifiable. Why?"
Falsifiable: the verifier found an instance where the check does not hold. A result, not an error.
Two questions that come back on nearly every station. The reasoning is not hard. Gathering the facts is:
Three parties, three different powers
Instantiates the model, runs the verifier, writes evidence into the project's own output folders.
Never interprets or explains a value.
Returns drafts and explanations as text only, and asks iLock for missing evidence.
Never edits a file, names a member the lookup did not return, or decides a fix is correct.
Owns the requirement's intent, checks every member, makes every change.
Formalization mistake, data-entry mistake or design fault: their call.
One request, end to end
Worked example 1: why a check failed
A data check requires a trackside tag to sit at least 600 m ahead of the level-crossing track. The verifier says Falsifiable.
"Why does this check fail in this project?"
The trace is partial evaluation: Prover iLock unfolds the failing predicate for concrete instances and records each sub-expression's value.
ALL lcra:SELF.associated_lc
SOME line (
objects_in_path(line, SELF) &
SOME lx:lcra.objects (
objects_in_path(line, lx) & (… lx.distance - SELF.distance >= 60000 …)))
Most cases are false only because objects_in_path is false: noise. One case binds a real line and a real level-crossing track:
Distance from tag to level-crossing track
5 m shortlx.distance - SELF.distance == 59500 cm against >= 60000. The model counts centimetres (and milliseconds), so the agent quotes raw value and conversion.
As here: design fault
move the tagThe table agrees: 59500 cm, no factor of 100. The design itself is wrong. No predicate is touched.
Twin case: data entry
fix the tableHad the table said 595 while the model counts centimetres: a unit mistake, fixed in the table.
The agent lays out both, with evidence. Choosing, and moving equipment on a live railway, is the engineer's judgment.
Worked example 2: from a sentence to a predicate
"The maximum distance between two consecutive tags shall not be more than 1000 m."
Rule: never reference a member the lookup did not return; a missing one becomes an open question.
"""
The maximum distance between two consecutive tags shall not be
more than 1000m.
Note: Formalized as |SELF.distance - adjacent.distance| <= 100000 cm.
Traceability: <specification clause>
"""
DATACHECK_<clause>_max_tag_distance :=
ALL rf:SELF.adjacent_tag (
// 1000m = 100000 cm
(SELF.distance - rf.distance <= 100000) &
(rf.distance - SELF.distance <= 100000)
);
Does the restatement mean what the requirement means?
Does every named member exist on the class?
Is the unit right? 1000 m = 100000 cm.
All three hold: the engineer pastes it in. If a draft looks doubtful, one question settles it:
"Show me which object-model members and existing predicates you used for that draft."
A grounded answer can name them. An invented one cannot.
The words used above
Object model
The classes describing things on the railway, with parameters and variables.
PiSPEC
The specification language Prover iLock models are written in.
Data check (static invariant)
A predicate that must hold for every instance of a class, given the design data.
Falsifiable
An instance fails the check. A result, not an error; it names the instances.
Traceability reference
The clause reference linking requirement, predicate and report row.
Partial evaluation
Unfolding a failing predicate for concrete instances. The raw material for a root cause, and why it is slow.
MCP server
A small local program on the engineer's machine; it sends nothing anywhere on its own.
Agent
The AI assistant that decides which tools to call, in what order, and writes the answer.