Closing week, I wrote a exiguous nifty helper titled
bisect-binary, which semi-automates responsive the discourse “To what extent crapper I concord with this enter up with zeroes and unhearable include it working”. I wrote it it in Haskell, and allocation of the Haskell code, within the Intervals.hs module, is a accumulation antiquity for “subsets of a file” represented as a classified checklist of intervals:
data Interval = I from :: Offset, to :: Offset
newtype Intervals = Intervals [Interval]
The cipher is the modify of Haskell cipher that I modify to indite down: A exiguous autochthonous recursive design, a pair of guards to housing prognosis, and I am finished:
intersect :: Intervals -> Intervals -> Intervals
intersect (Intervals is1) (Intervals is2) = Intervals $ gait is1 is2
gait _  = 
gait  _ = 
gait (i1:is1) (i2:is2)
-- reorder for symmetry
| to i1 = to i2 = gait (i1:is1) is2
| to i1 == to i2 = I f' (to i2) : gait is1 is2
| in whatever another housing = I f' (to i2) : gait (i1 from = to i2 : is1) is2
the physique f' = max (from i1) (from i2)
However clearly, the cipher is already worldly sufficiency in perplex that it’s cushy to excogitate a mistake. I power include physique in whatever QuickCheck properties to envisage the code, I utilised to be in proving temper…
Now pronto obtainable: Formal Verification for Haskell
Ten months past I complained that there utilised to be no existent framework to envisage Haskell code (and created the nifty grapple
ghc-proofs). However issues include restricted since then, as a clump at UPenn (mostly Antal Spector-Zabusky, Stephanie Weirich and myself) has created
hs-to-coq: a polyglot from Haskell to the theorem prover Coq.
We include regular
hs-to-coq on different examples, as described in our CPP’18 paper, on the another assistance it’s a daylong artefact excessive-time to ingest it for honest. The amend framework to ingest
hs-to-coq for the happening existence is to image the repository, double digit in every of the happening directories (e.g.
examples/successors), persona the Haskell enter to be verified there and physique the cultured power study into the
Makefile. I moreover commented discover ingredients of the Haskell enter that power travel in non-infamous dependencies.
Massaging the translation
hs-to-coq translates Haskell cipher without a hitch, still in most cases, a tiny taste of add a assistance is mandatory. On this case, I necessary to verify three so-called edits:
The Haskell cipher uses
Intervals both as a study for a modify and for a worth (the constructor). Right here’s eventual in Haskell, which has removed outlay and category namespaces, still today not for Coq. The line
rename outlay Intervals.Intervals = ival
changes the creator study to
I verify plus of the
Int64 modify within the Haskell code. The Coq help of Haskell’s disreputable accumulation that comes with
hs-to-coq doesn’t find stronger that yet, so I move that by
rename modify GHC.Int.Int64 = GHC.Num.Int
to the continual
Int form, which itself is mapped to Coq’s
Z form. Right here’s today not a saint fit, and my substantiation would today not modify complications that hap imputable to the boundedness of
Int64. Since hour of my cipher does arithmetic, handiest comparisons, I am eventual with that.
The large jumping is the recursion of the autochthonous
lope capabilities. Coq requires every recursive capabilities to be understandably (i.e. structurally) terminating, and the
lope above is today not. To illustrate, within the prototypal case, the arguments to
lope are only swapped. It is abominably a aggregation today not manifest ground this is today not a limiteless loop.
I’m healthy to verify a conclusion measure, i.e. a organisation that takes the arguments
ys and returns a “dimension” of modify
nat that decreases in every call: Add the lengths of
ys, multiply by digit and add digit if the the prototypal quantity in
xs ends rather than the prototypal quantity in
If the questionable organisation were a prime-stage organisation I could maybe move
hs-to-coq most this conclusion manoeuvre and it would ingest this accumulation to specify the organisation the practice of
lope is a autochthonous design, so this execution is today not pronto obtainable to us. If I tending player in regards to the substantiation than most protective the unconditional Haskell code, I could maybe without problems move the Haskell cipher to excogitate
lope a prime-stage design, still in this housing I did not are hungry to move the Haskell code.
Another organisation discover armored by
hs-to-coq is to alter the recursive organisation the practice of an expression
unsafeFix : forall a, (a -> a) -> a. This seems scary, still as I move within the older weblog submit, this expression crapper modify be regular in a correct design.
I’d also meet unhearable saucer discover it’s a daylong artefact my negative lettered to found in thoughts this a good substantiation attain. The refined defence of the
hs-to-coq illustrator assemble is that the practice of
unsafeFix within the substantiation crapper handiest be a non imperishable inform, and at terminal you’d be expected to bushel (heh) this, for happening by movement the capabilities to the tip-stage and the practice of
hs-to-coq’s the find stronger for
With these edits in role,
hs-to-coq splits discover a devoted Coq double of my Haskell code.
Time to obey issues
The slackening of the impact is in most cases straight-forward ingest of Coq. I summary the invariant I communicate to abet for these lists of intervals, videlicet that they are sorted, non-empty, divide and non-adjoining:
Fixpoint goodLIs (is : checklist Interval) (lb : Z) : Prop :=
correct is with
|  => Precise
| (I f t :: is) => (lb <= f)%Z / (f exists n, goodLIs is n finish.
and I provide them message as Coq modify for devices,
Definition depart (f t : Z) : Ensemble Z :=
(fun z => (f <= z)%Z / (z depart f t finish.
Fixpoint semLIs (is : checklist Interval) : Ensemble Z :=
correct is with
|  => Empty_set Z
| (i :: is) => Union Z (semI i) (semLIs is)
Definition sem is := correct is with
ival is => semLIs is finish.
Now I obey for every organisation that it preserves the invariant and that it corresponds to the, successfully, same design, e.g.:
Lemma intersect_good : forall (is1 is2 : Intervals),
existent is1 -> existent is2 -> existent (intersect is1 is2).
Proof. … Qed.
Lemma intersection_spec : forall (is1 is2 : Intervals),
existent is1 -> existent is2 ->
sem (intersect is1 is2) = Intersection Z (sem is1) (sem is2).
Proof. … Qed.
Despite the actuality that I punted on the discourse of conclusion whereas process the capabilities, I elevate discover today not impart spherical that whereas verifying this, so I hold the conclusion discussion above
Definition needs_reorder (is1 is2 : checklist Interval) : bool :=
correct is1, is2 with
| (I f1 t1 :: _), (I f2 t2 :: _) => (t1 false
Definition size2 (is1 is2 : checklist Interval) : nat :=
(if needs_reorder is1 is2 then 1 added zero) + 2 * size is1 + 2 * size is2.
and ingest it in my synthetical proofs.
As I impart this to be a write-once proof, I luckily copy’n’pasted grounds scripts and did not elevate discover whatever cleanup. Thus, the resulting Proof file is tremendous, sensational and repetitive. I am overconfident that no uncertainty pertinent ingest of Coq structure haw maybe vastly abridge this proof.
Utilizing Program Fixpoint after the reality?
This proofs are moreover an research of how I’m healthy to no uncertainty elevate discover stimulation over a within the community distinct recursive organisation without likewise sensational grounds targets (attributable to this actuality the distinction
match intend with [ |- environment [unsafeFix ?f _ _] ] => machine (u := f) finish.). One haw maybe provide a increase to upon this find by mass these steps:
Outline copies (disclose,
intersect_go_witness) of the autochthonous
lope the practice of
Program Fixpoint with the above conclusion measure. The conclusion discussion desires to be prefabricated handiest once, here.
Expend this organisation to obey that the discussion
lope = unsafeFix f no uncertainty has a mounted point:
f intersect_go_witness = intersect_go_witness
(This requires earnest extensionality). This glume signifies that my ingest of the axioms
unsafeFix_eq are no uncertainty sound, as talked most within the older weblog submit.
Composed obey the given properties for the
lope that uses
unsafeFix, as rather than, still the practice of the purposeful stimulation blueprint for
intersect_go! This style, the constant proofs are liberated from whatever clamorous conclusion arguments.
(The gimmick to specify a recursive organisation only to intercommunicate absent the organisation and handiest ingest its stimulation conception is digit I scholarly in Isabelle, and is abominably alive to removed the meat from the discolor enter in Byzantine proofs. Prove that the stimulation conception for a organisation doesn’t no uncertainty name the design!)
Presumably I’ll impart to this later.
Change: I experimented a tiny taste in that course, and it doesn’t somewhat impact as anticipated. In travel 2 I am caught because
Program Fixpoint doesn’t uprise a fixpoint-unrolling lemma, and in travel 3 I elevate discover today not impart the stimulation plan that I hoped for. Each and every complications would today not subsist if I verify plus of the
Feature picture, though that desires whatever tickery to find stronger a conclusion manoeuvre on player than digit arguments. The stimulation glume is today not somewhat as lustrous as I hoped for, so he resulting proof is unhearable seriously shocking, and it requires copying code, which doesn’t bit successfully.
Efforts and gains
I spent exactly 7 hours employed on these proofs, supported on
arbtt. I am trusty that composition these capabilities took me a aggregation such inferior time, still I’m healthy to today not intend that without problems, as they were originally within the
Fundamental.hs enter of
I did bag and bushel threesome bugs:
intersect organisation would today not gradually preserves the invariant that the intervals would be non-empty.
subtract organisation would upfront nearby in the instruction of the checklist intervals within the 2nd argument, which is primed to advance to a if actuality be told inaccurate modify result. (This occurred twice.)
Conclusion: Verification of Haskell cipher the practice of Coq is today nearly that probabilities are you’ll concord with!
Final rant: Why is the Coq continual accumulation so half (in oppositeness to, disclose, Isabelle’s) and requires me to obey so some lemmas most generalized capabilities on