Separation logic, sort-erased #
The whole theory lives here, the solver functions included: a separation-logic term's well-formedness depends on the heap a solver declared, not only on its operands.
The heap is declared, and everything hangs off that #
Solver.declareSepHeap fixes the heap's location and data sorts, once per solver, and cvc5 checks
nothing else against them: (pto 1 true) is built without complaint against a heap of
Loc × Int and fails only at check-sat, reporting a type error about set.union — cvc5's internal
encoding showing through.
So declareSepHeap answers a handle, and the two heap-dependent constructors hang off it:
Heap.pto, which checks its operands against the sorts the handle carries;Heap.nil, which buildssep.nilat the heap's location sort rather than at any sort a caller might name.
The handle is indexed by the solver that produced it: two solvers of one scope may declare different heaps.
sepEmp, sepStar and sepWand mention no heap sort, so they need no handle. None of these
operators is lifted over nullables.
Separating implication, the magic wand.
Equations
- lft.sepWand rgt = Cvc.runUnsafe✝ fun (tm : cvc5.TermManager) => tm.mkTerm cvc5.Kind.SEP_WAND #[lft, rgt]
Instances For
sepStar over two or more terms.
Equations
- Cvc.Untyped.Term.sepStarN terms atLeastTwoElements = Cvc.runUnsafe✝ fun (tm : cvc5.TermManager) => tm.mkTerm cvc5.Kind.SEP_STAR terms
Instances For
Holds exactly when the heap is empty.
Equations
- Cvc.Untyped.Term.sepEmp = Cvc.runUnsafe✝ fun (tm : cvc5.TermManager) => tm.mkSepEmp
Instances For
Separating conjunction: the heap splits in two, one part satisfying each side.
Equations
- lft.sepStar rgt = Cvc.runUnsafe✝ fun (tm : cvc5.TermManager) => tm.mkTerm cvc5.Kind.SEP_STAR #[lft, rgt]
Instances For
Sep's operators, taken apart one level, sort-erased.
- sepEmp
[Ω]
: View.Sep
Holds exactly when the heap is empty.
- sepStar
[Ω]
(kids : Kids)
: View.Sep
Separating conjunction: the heap splits in two, one part satisfying each side.
kidsholds every operand, two or more. - sepWand
[Ω]
(lft rgt : Term)
: View.Sep
Separating implication, the magic wand.
Instances For
The heap of a solver, and the sorts it was declared at.
Produced by declareSepHeap, and the only way to Heap.pto or Heap.nil.
Instances For
Equations
Declares the heap's location and data sorts, and answers the handle they are reached through.
cvc5 allows this once per solver, and rejects a second call even at the same sorts. It has to come before any separation-logic constraint: asserting one against an undeclared heap is an error.
Equations
- s.declareSepHeap loc data = do Cvc.runUnsafe'✝ ((Cvc.Untyped.Solver.toUnsafe✝ s).declareSepHeap loc data) pure { loc := loc, data := data }
Instances For
sep.nil, the null location, at the heap's location sort.
Equations
- h.nil = Cvc.runUnsafe✝ fun (tm : cvc5.TermManager) => tm.mkSepNil h.loc
Instances For
The points-to constraint: loc points to data in a heap holding nothing else.
The operands are checked against the sorts the heap was declared at, which cvc5 does not do until
check-sat — and then reports as a set.union type error naming neither pto nor the heap.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Reading a heap back #
A formula describing the model's heap, such as (pto (as @Loc_1 Loc) 0); not a value.
Equations
Instances For
getValueSepHeap in Env, not checked to follow a sat answer.