Fil-C on Nix

Filnix wiki

the formal campaign

rocq/backend/Order.v

Prolog's standard order of terms, and the sorted lists the Prolog compiler makes with it: sort/2, msort/2 and the ordsets of library(ordsets). The backend's plans list temporaries, live ranges and thunks in this order, so the Gallina backend sorts by it too.

For the ground terms of Term.v the order is: integers by value, then [ ], then atoms by character code, then compounds, by arity, then by name, then by their arguments from the left. A list that is not empty is the compound '[|]'(Head, Tail).

From Stdlib Require Import String ZArith List Ascii
From Nanofil Require Import Term
Import ListNotations

Comparing

The order of two atoms' names: by character code, a prefix first. Extract.v makes it OCaml's comparison of strings.

20Definition atom_comparea b : string : comparison ≔
String.comparea b

c, or d if c finds its two sides equal: one more key of a comparison by several.

24Definition thencc d : comparison : comparison ≔
match c with
⇒
d
_
⇒
c

As compare(Order, T, U): the standard order of the terms t and u.

29Fixpoint term_comparet u : term {struct t} : comparison ≔
let fix args_compare ts us : listterm {struct ts} : comparison ≔
match ts, us with
[ ], [ ]
⇒
[ ], _ :: _
⇒
_ :: _, [ ]
⇒
t′ :: ts′, u′ :: us′
⇒
thencterm_comparet′ u′ args_comparets′ us′
in
let fix list_compare ts : listterm u : term {struct ts} : comparison ≔
match ts with

The list ts against the term u.

[ ]
⇒
match u with
⇒
⇒
_
⇒
h :: ts′
⇒
match u with
TInt_ | TAtom_ | TList[ ]
⇒
TListh′ :: us′
⇒
thencterm_compareh h′ list_comparets′ TListus′
TAppg b1; b2
⇒
thencatom_compare"[|]" g thencterm_compareh b1 list_comparets′ b2
TApp_ bs
⇒
Nat.compare2 lengthbs
in
match t with
⇒
match u with
⇒
Z.comparen m
_
⇒
⇒
match u with
TInt_ | TList[ ]
⇒
_
⇒
⇒
list_comparets u
TAppf ts
⇒
match u with
TInt_ | TAtom_ | TList[ ]
⇒
TAppg us
⇒
thencNat.comparelengthts lengthus thencatom_comparef g args_comparets us
TListh′ :: us′
⇒
match ts with
_
⇒
Nat.comparelengthts 2

Sorting

80Section Sorting
81Context A : Type cmp : A → A → comparison

The sorted lists xs and ys merged; of two equal elements, xs's comes first.

85Fixpoint mergexs : listA : listA → listA ≔
fix merge_into ys : listA : listA ≔
match xs, ys with
[ ], _
⇒
ys
_, [ ]
⇒
xs
x :: xs′, y :: ys′
⇒
match cmpx y with
⇒
y :: merge_intoys′
_
⇒
x :: mergexs′ ys

A merge sort's stack of sorted runs: the run at depth i, if there is one, has 2^i elements.

99Fixpoint push_runstack : listoptionlistA run : listA : listoptionlistA ≔
match stack with
[ ]
⇒
Somerun
None :: stack′
⇒
Somerun :: stack′
Somerun′ :: stack′
⇒
None :: push_runstack′ mergerun′ run

The runs of a stack merged, the oldest first.

108Fixpoint merge_runsstack : listoptionlistA : listA ≔
match stack with
[ ]
⇒
[ ]
None :: stack′
⇒
merge_runsstack′
Somerun :: stack′
⇒
mergemerge_runsstack′ run

As msort(Xs, Sorted): xs in the order of cmp, equal elements in the order they had (a merge sort, as SWI-Prolog's is).

117Definition msortxs : listA : listA ≔
merge_runsfold_leftλstack x ⇒ push_runstack x xs [ ]

A sorted list with one element of each run of equal ones.

121Fixpoint dedupxs : listA : listA ≔
match xs with
x :: y :: _ as xs′
⇒
match cmpx y with
⇒
dedupxs′
_
⇒
x :: dedupxs′
_
⇒
xs

As sort(Xs, Sorted): xs sorted, without duplicates. Its results are ordsets.

130Definition sortxs : listA : listA ≔

As ord_union(Xs, Ys, Zs): the union of two ordsets.

133Fixpoint ord_unionxs : listA : listA → listA ≔
fix union_into ys : listA : listA ≔
match xs, ys with
[ ], _
⇒
ys
_, [ ]
⇒
xs
x :: xs′, y :: ys′
⇒
match cmpx y with
⇒
x :: ord_unionxs′ ys
⇒
x :: ord_unionxs′ ys′
⇒
y :: union_intoys′

As ord_subtract(Xs, Ys, Zs): the elements of the ordset xs that are not in the ordset ys.

148Fixpoint ord_subtractxs : listA : listA → listA ≔
fix subtract_from ys : listA : listA ≔
match xs, ys with
[ ], _
⇒
[ ]
_, [ ]
⇒
xs
x :: xs′, y :: ys′
⇒
match cmpx y with
⇒
x :: ord_subtractxs′ ys
⇒
ord_subtractxs′ ys′
⇒
subtract_fromys′

Whether two ordsets of names are the same.

163Fixpoint names_eqbxs ys : listname : bool ≔
match xs, ys with
[ ], [ ]
⇒
true
x :: xs′, y :: ys′
⇒
name_eqbx y && names_eqbxs′ ys′
_, _
⇒
false
170Example order_kinds: msortterm_compare TApp"g" TAtom"a"; TAtom"b"; TListTAtom"a"; TAtom"b"; TApp"-" TAtom"a"; TAtom"b"; TList[ ]; TInt3; TAtom"a"; TInt−1 = TInt−1; TInt3; TList[ ]; TAtom"a"; TAtom"b"; TApp"-" TAtom"a"; TAtom"b"; TListTAtom"a"; TApp"g" TAtom"a"; TAtom"b"
Proof 1 step Qed
reflexivity
179Example sort_dedups: sortZ.compare 3; 1; 2; 3; 1%Z = 1; 2; 3%Z
Proof 1 step Qed
reflexivity