-
Notifications
You must be signed in to change notification settings - Fork 0
/
SplitRec.v
73 lines (58 loc) · 1.95 KB
/
SplitRec.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
From PlutusCert Require Import
PlutusIR
Analysis.FreeVars
Analysis.UniqueBinders
Analysis.WellScoped
Transform.Compat
.
Import NamedTerm.
Import Term.
From Coq Require Import
Strings.String
Lists.List
Lists.ListSet
.
Import ListNotations.
(* A binding group (Let without a body) *)
Definition binding_group := (Recursivity * list Binding)%type.
(*
Assuming globally unique variables, the new binding groups much satisfy:
- Well-scoped: each free variable in a binding RHS is bound
- All bindings equals those in the let-rec before transformaton
Note that strictness of bindings does not matter: if one of the (strict)
bindings diverges, the whole let-block diverges. This behaviour remains when
regrouping/reordering all bindings.
*)
Definition list_eq_elems {A} xs ys : Prop :=
forall (x : A), In x xs <-> In x ys.
Definition min_Rec (r1 r2 : Recursivity) : Recursivity :=
match r1, r2 with
| NonRec, NonRec => NonRec
| _ , _ => Rec
end.
(* Collect subsequent binding groups, together with the "inner" term and
minimum recursivity *)
Inductive outer_binds : Term -> list Binding -> Term -> Recursivity -> Prop :=
| cv_Let : forall t_body lets t_inner r bs r_body,
outer_binds t_body lets t_inner r_body ->
outer_binds (Let r bs t_body) (bs ++ lets) t_inner (min_Rec r_body r)
| cv_Other : forall t_inner,
outer_binds t_inner [] t_inner NonRec
.
Inductive split_syn : Term -> Term -> Prop :=
| split_rec_let : forall bs t_body t bgs t_inner min_rec,
(* a decision-procedure would need to find the list bgs of binding groups that
satisfies the second premise (needs to do backtracking) *)
outer_binds t bgs t_inner min_rec ->
list_eq_elems bs bgs ->
split_syn t_body t_inner ->
split_syn (Let Rec bs t_body) t
| split_rec_cong : forall t t',
Compat split_syn t t' ->
split_syn t t'
.
Definition split_rec t t' :=
split_syn t t' /\
unique t /\
closed t'
.