Skip to content

Commit 817c375

Browse files
committed
Port to derive.param2 of Coq-Elpi
1 parent 49c3785 commit 817c375

File tree

6 files changed

+84
-72
lines changed

6 files changed

+84
-72
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ slices in the input.
5959
- License: [CeCILL-B Free Software License Agreement](CeCILL-B)
6060
- Compatible Coq versions: 8.13 or later
6161
- Additional dependencies:
62+
- [Coq-Elpi](https://github.com/LPCIC/coq-elpi)
6263
- [MathComp](https://math-comp.github.io) 1.13.0 or later
63-
- [Paramcoq](https://github.com/coq-community/paramcoq) 1.1.3 or later
6464
- [Mczify](https://github.com/math-comp/mczify) (required only for the test suite)
6565
- [Equations](https://github.com/mattam82/Coq-Equations) (required only for the test suite)
6666
- Coq namespace: `stablesort`

coq-stablesort.opam

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ run-test: [ [make "-j%{jobs}%" "build-misc" ] { coq:version < "8.17~" | "8.18~"
5858
install: [make "install"]
5959
depends: [
6060
"coq" {>= "8.13"}
61+
"coq-elpi"
6162
"coq-mathcomp-ssreflect" {>= "1.13.0"}
62-
"coq-paramcoq" {>= "1.1.3"}
6363
"coq-mathcomp-zify" {with-test}
6464
"coq-equations" {with-test}
6565
]

meta.yml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -169,16 +169,15 @@ tested_coq_opam_versions:
169169
repo: 'mathcomp/mathcomp-dev'
170170

171171
dependencies:
172+
- opam:
173+
name: coq-elpi
174+
description: |-
175+
[Coq-Elpi](https://github.com/LPCIC/coq-elpi)
172176
- opam:
173177
name: coq-mathcomp-ssreflect
174178
version: '{>= "1.13.0"}'
175179
description: |-
176180
[MathComp](https://math-comp.github.io) 1.13.0 or later
177-
- opam:
178-
name: coq-paramcoq
179-
version: '{>= "1.1.3"}'
180-
description: |-
181-
[Paramcoq](https://github.com/coq-community/paramcoq) 1.1.3 or later
182181
- opam:
183182
name: coq-mathcomp-zify
184183
version: '{with-test}'

misc/topdown_tailrec.v

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,20 @@ Lemma if_nilp (T S : Type) (s : seq T) (x y : S) :
1313
(if nilp s then x else y) = if s is [::] then x else y.
1414
Proof. by case: s. Qed.
1515

16+
(* We define a non-mutual-fixpoint alternative of ssrnat.half, so that *)
17+
(* derive.param2 accepts it. *)
18+
Fixpoint half' (n : nat) : nat :=
19+
match n with
20+
| n.+2 => (half' n).+1
21+
| _ => 0
22+
end.
23+
24+
Lemma half'E : half' =1 half.
25+
Proof.
26+
move=> n; have [m ltnm] := ubnP n.
27+
by elim: m n ltnm => // m IHm [|[|n]] //= /ltnW /IHm ->.
28+
Qed.
29+
1630
Section Revmerge.
1731

1832
Context (T : Type) (leT : rel T).
@@ -55,7 +69,7 @@ Equations sort_rec (xs : seq T) (b : bool) (n fuel : nat) :
5569
(* end absurd cases *)
5670
sort_rec (x :: xs) _ 1 _ => (singleton x, xs);
5771
sort_rec xs b n fuel.+1 =>
58-
let n1 := n./2 in
72+
let n1 := half' n in
5973
let (s1, xs') := sort_rec xs (~~ b) n1 fuel in
6074
let (s2, xs'') := sort_rec xs' (~~ b) (n - n1) fuel in
6175
((if b then merge' s1 s2 else merge s1 s2), xs'').
@@ -66,7 +80,13 @@ Definition sort (xs : seq T) : R :=
6680

6781
End Abstract.
6882

69-
Parametricity sort.
83+
Elpi derive.param2 size.
84+
Elpi derive.param2 fst.
85+
Elpi derive.param2 half'.
86+
Elpi derive.param2 Nat.sub.
87+
Elpi derive.param2 subn.
88+
Elpi derive.param2 sort_rec.
89+
Elpi derive.param2 sort.
7090

7191
End Abstract.
7292

@@ -109,7 +129,7 @@ rewrite {}/rhs; move: {2 4}(size xs) => fuel.
109129
apply_funelim (sort_rec xs true (size xs) fuel);
110130
try by move=> *; case: (b in condrev b).
111131
move=> x {}xs b n {}fuel IHl IHr.
112-
rewrite Abstract.sort_rec_equation_5 /= {}IHl /= {IHr}(IHr [::]) /=.
132+
rewrite Abstract.sort_rec_equation_5 /= !half'E {}IHl /= {IHr}(IHr [::]) /=.
113133
case: (sort_rec (x :: xs)) => s1 xs' /=; case: sort_rec => s2 xs'' /=.
114134
by rewrite !revmergeE /condrev; case: b; rewrite /= !revK.
115135
Qed.
@@ -129,7 +149,7 @@ apply_funelim
129149
- by [].
130150
- by move=> x {}xs; rewrite /= take0 drop0.
131151
move=> x {}xs b n {}fuel IHl IHr; rewrite ltnS => n_lt_fuel.
132-
rewrite [LHS]/= {}IHl 1?{}(IHr [::]) 1?if_same; try lia.
152+
rewrite [LHS]/= {}IHl 1?{}(IHr [::]) 1?if_same half'E; try lia.
133153
rewrite -takeD drop_drop; congr (take _ _, drop _ _); lia.
134154
Qed.
135155

theories/param.v

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,24 @@
1+
From elpi.apps Require Export derive.param2.
12
From mathcomp Require Import ssreflect ssrfun ssrbool eqtype ssrnat seq path.
2-
From Param Require Export Param.
33

44
Set Implicit Arguments.
55
Unset Strict Implicit.
66
Unset Printing Implicit Defensive.
77

8-
Ltac destruct_reflexivity :=
9-
intros ; repeat match goal with
10-
| [ x : _ |- _ = _ ] => destruct x; reflexivity; fail
11-
end.
12-
13-
Global Parametricity Tactic := ((destruct_reflexivity; fail) || auto).
14-
15-
Parametricity False.
16-
Parametricity eq.
17-
Parametricity or.
18-
Parametricity Acc.
19-
Parametricity unit.
20-
Parametricity bool.
21-
Parametricity option.
22-
Parametricity prod.
23-
Parametricity nat.
24-
Parametricity list.
25-
Parametricity pred.
26-
Parametricity rel.
27-
Parametricity BinNums.positive.
28-
Parametricity BinNums.N.
29-
Parametricity merge.
30-
Parametricity rev.
8+
Elpi derive.param2 bool.
9+
Elpi derive.param2 nat.
10+
Elpi derive.param2 option.
11+
Elpi derive.param2 prod.
12+
Elpi derive.param2 list.
13+
Elpi derive.param2 pred.
14+
Elpi derive.param2 rel.
15+
Elpi derive.param2 negb.
16+
Elpi derive.param2 addb.
17+
Elpi derive.param2 eqb.
18+
Elpi derive.param2 merge.
19+
Elpi derive.param2 catrev.
20+
Elpi derive.param2 rev.
21+
Elpi derive.param2 foldr.
3122

3223
Lemma bool_R_refl b1 b2 : b1 = b2 -> bool_R b1 b2.
3324
Proof. by case: b1 => <-; constructor. Qed.

theories/stablesort.v

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ Definition asort_ty :=
5454
seq T -> (* input *)
5555
R. (* output *)
5656

57-
Parametricity sort_ty.
58-
Parametricity asort_ty.
57+
Elpi derive.param2 sort_ty.
58+
Elpi derive.param2 asort_ty.
5959

6060
Structure function := Pack {
6161
(* the sort function *)
@@ -255,7 +255,7 @@ Definition sort (T R : Type) (leT : rel T)
255255
(merge merge' : R -> R -> R) (singleton : T -> R) (empty : R) :=
256256
foldr (fun x => merge (singleton x)) empty.
257257

258-
Parametricity sort.
258+
Elpi derive.param2 sort.
259259

260260
End Abstract.
261261

@@ -350,27 +350,34 @@ Fixpoint sort3rec (stack : seq (option R)) (xs : seq T) : R :=
350350
Definition sort3 : seq T -> R := sort3rec [::].
351351

352352
Fixpoint sortNrec (stack : seq (option R)) (x : T) (xs : seq T) : R :=
353-
if xs is y :: xs then
354-
sortNrec' (leT x y) stack y xs (singleton x) else pop (singleton x) stack
355-
with sortNrec' (incr : bool) (stack : seq (option R))
356-
(x : T) (xs : seq T) (accu : R) : R :=
353+
let fix sortNrec' (incr : bool) (stack : seq (option R))
354+
(x : T) (xs : seq T) (accu : R) : R :=
357355
let accu' := (if incr then merge' else merge) accu (singleton x) in
358356
if xs is y :: xs then
359357
if eqb incr (leT x y) then
360358
sortNrec' incr stack y xs accu' else sortNrec (push accu' stack) y xs
361359
else
362-
pop accu' stack.
360+
pop accu' stack
361+
in
362+
if xs is y :: xs then
363+
sortNrec' (leT x y) stack y xs (singleton x) else pop (singleton x) stack.
363364

364365
#[using="All"]
365366
Definition sortN (xs : seq T) : R :=
366367
if xs is x :: xs then sortNrec [::] x xs else empty.
367368

368369
End Abstract.
369370

370-
Parametricity sort1.
371-
Parametricity sort2.
372-
Parametricity sort3.
373-
Parametricity sortN.
371+
Elpi derive.param2 pop.
372+
Elpi derive.param2 push.
373+
Elpi derive.param2 sort1rec.
374+
Elpi derive.param2 sort1.
375+
Elpi derive.param2 sort2rec.
376+
Elpi derive.param2 sort2.
377+
Elpi derive.param2 sort3rec.
378+
Elpi derive.param2 sort3.
379+
Elpi derive.param2 sortNrec.
380+
Elpi derive.param2 sortN.
374381

375382
End Abstract.
376383

@@ -512,13 +519,10 @@ case=> // x xs; have [n] := ubnP (size xs).
512519
rewrite /Abstract.sortN /sortN -[Nil (option _)]/(astack_of_stack [::]).
513520
elim: n (Nil (seq _)) x xs => // n IHn stack x [|y xs /= /ltnSE Hxs].
514521
by rewrite [LHS]apop_mergeE.
515-
rewrite /Abstract.sortNrec -/(Abstract.sortNrec' _ _ _ _).
516522
have {1}->: [:: x] = condrev (leT x y) [:: x] by rewrite [RHS]if_same.
517523
move: xs Hxs x y (RS in x :: RS) {-2}(leT x y) (erefl (leT x y)).
518524
elim=> [_|z xs IHxs /= /ltnW Hxs] x y rs incr incrE.
519-
by rewrite /Abstract.sortNrec' apop_mergeE /= incrE mergeEcons; case: ifP.
520-
rewrite /Abstract.sortNrec'.
521-
rewrite -/(Abstract.sortNrec' _ _ _ _) -/(Abstract.sortNrec _ _ _ _).
525+
by rewrite apop_mergeE /= incrE mergeEcons; case: ifP.
522526
rewrite eqbE incrE mergeEcons apush_mergeE ?condrev_nilp // IHn //.
523527
by have [/[dup] /IHxs -> // ->|] := eqVneq; do 2?case: ifP.
524528
Qed.
@@ -564,12 +568,9 @@ case=> // x xs; have [n] := ubnP (size xs).
564568
rewrite /Abstract.sortN -[RHS]/(flatten_stack (x :: xs) [::]).
565569
elim: n x (Nil (option _)) xs => // n IHn x stack [|y xs /= /ltnSE Hxs];
566570
first by rewrite [LHS]apop_catE.
567-
rewrite /Abstract.sortNrec -/(Abstract.sortNrec' _ _ _ _).
568571
pose rs := Nil T; rewrite -[x :: y :: _]/(rs ++ _) -[[:: x]]/(rs ++ _).
569572
elim: xs Hxs x y rs => [_|z xs IHxs /= /ltnW Hxs] x y rs.
570573
by rewrite [LHS]apop_catE if_same -catA.
571-
rewrite /Abstract.sortNrec'.
572-
rewrite -/(Abstract.sortNrec' _ _ _ _) -/(Abstract.sortNrec _ _ _ _).
573574
move: (IHxs Hxs y z (rcons rs x)).
574575
by rewrite eqbE if_same IHn // apush_catE -cats1 -!catA; case: eqVneq => // ->.
575576
Qed.
@@ -678,29 +679,36 @@ Fixpoint sort3rec (stack : seq (option R)) (xs : seq T) : R :=
678679
Definition sort3 : seq T -> R := sort3rec [::].
679680

680681
Fixpoint sortNrec (stack : seq (option R)) (x : T) (xs : seq T) : R :=
681-
if xs is y :: xs then
682-
sortNrec' (leT x y) stack y xs (singleton x)
683-
else
684-
pop false (singleton x) stack
685-
with sortNrec' (incr : bool) (stack : seq (option R))
686-
(x : T) (xs : seq T) (accu : R) : R :=
682+
let fix sortNrec' (incr : bool) (stack : seq (option R))
683+
(x : T) (xs : seq T) (accu : R) : R :=
687684
let accu' := (if incr then merge' else merge) accu (singleton x) in
688685
if xs is y :: xs then
689686
if eqb incr (leT x y) then
690687
sortNrec' incr stack y xs accu' else sortNrec (push accu' stack) y xs
691688
else
692-
pop false accu' stack.
689+
pop false accu' stack
690+
in
691+
if xs is y :: xs then
692+
sortNrec' (leT x y) stack y xs (singleton x)
693+
else
694+
pop false (singleton x) stack.
693695

694696
#[using="All"]
695697
Definition sortN (xs : seq T) : R :=
696698
if xs is x :: xs then sortNrec [::] x xs else empty.
697699

698700
End Abstract.
699701

700-
Parametricity sort1.
701-
Parametricity sort2.
702-
Parametricity sort3.
703-
Parametricity sortN.
702+
Elpi derive.param2 pop.
703+
Elpi derive.param2 push.
704+
Elpi derive.param2 sort1rec.
705+
Elpi derive.param2 sort1.
706+
Elpi derive.param2 sort2rec.
707+
Elpi derive.param2 sort2.
708+
Elpi derive.param2 sort3rec.
709+
Elpi derive.param2 sort3.
710+
Elpi derive.param2 sortNrec.
711+
Elpi derive.param2 sortN.
704712

705713
End Abstract.
706714

@@ -864,13 +872,10 @@ case=> // x xs; have [n] := ubnP (size xs).
864872
rewrite /Abstract.sortN /sortN -[Nil (option _)]/(astack_of_stack false [::]).
865873
elim: n (Nil (seq _)) x xs => // n IHn stack x [|y xs /= /ltnSE Hxs].
866874
by rewrite [LHS]apop_mergeE.
867-
rewrite /Abstract.sortNrec -/(Abstract.sortNrec' _ _ _ _).
868875
have {1}->: [:: x] = condrev (leT x y) [:: x] by rewrite [RHS]if_same.
869876
move: xs Hxs x y (RS in x :: RS) {-2}(leT x y) (erefl (leT x y)).
870877
elim=> [_|z xs IHxs /= /ltnW Hxs] x y rs incr incrE.
871-
by rewrite /Abstract.sortNrec' apop_mergeE /= incrE mergeEcons; case: ifP.
872-
rewrite /Abstract.sortNrec'.
873-
rewrite -/(Abstract.sortNrec' _ _ _ _) -/(Abstract.sortNrec _ _ _ _).
878+
by rewrite apop_mergeE /= incrE mergeEcons; case: ifP.
874879
rewrite eqbE incrE mergeEcons apush_mergeE ?condrev_nilp // IHn //.
875880
by have [/[dup] /IHxs -> // ->|] := eqVneq; do 2?case: ifP.
876881
Qed.
@@ -923,12 +928,9 @@ case=> // x xs; have [n] := ubnP (size xs).
923928
rewrite /Abstract.sortN -[RHS]/(flatten_stack (x :: xs) [::]).
924929
elim: n x (Nil (option _)) xs => // n IHn x stack [|y xs /= /ltnSE Hxs];
925930
first by rewrite [LHS]apop_catE.
926-
rewrite /Abstract.sortNrec -/(Abstract.sortNrec' _ _ _ _).
927931
pose rs := Nil T; rewrite -[x :: y :: _]/(rs ++ _) -[[:: x]]/(rs ++ _).
928932
elim: xs Hxs x y rs => [_|z xs IHxs /= /ltnW Hxs] x y rs.
929933
by rewrite [LHS]apop_catE if_same -catA.
930-
rewrite /Abstract.sortNrec'.
931-
rewrite -/(Abstract.sortNrec' _ _ _ _) -/(Abstract.sortNrec _ _ _ _).
932934
move: (IHxs Hxs y z (rcons rs x)).
933935
by rewrite eqbE if_same IHn // apush_catE -cats1 -!catA; case: eqVneq => // ->.
934936
Qed.

0 commit comments

Comments
 (0)