aboutsummaryrefslogtreecommitdiff
path: root/src/Compilers/Relations.v
diff options
context:
space:
mode:
Diffstat (limited to 'src/Compilers/Relations.v')
-rw-r--r--src/Compilers/Relations.v368
1 files changed, 368 insertions, 0 deletions
diff --git a/src/Compilers/Relations.v b/src/Compilers/Relations.v
new file mode 100644
index 000000000..27a101e4f
--- /dev/null
+++ b/src/Compilers/Relations.v
@@ -0,0 +1,368 @@
+Require Import Coq.Lists.List Coq.Classes.RelationClasses Coq.Classes.Morphisms.
+Require Import Crypto.Compilers.Syntax.
+Require Import Crypto.Compilers.SmartMap.
+Require Import Crypto.Compilers.Wf.
+Require Import Crypto.Util.Tactics.RewriteHyp.
+Require Import Crypto.Util.Tactics.DestructHead.
+Require Import Crypto.Util.Tactics.SplitInContext.
+Require Import Crypto.Util.Prod.
+Require Import Crypto.Util.Sigma.
+
+Local Coercion is_true : bool >-> Sortclass.
+
+Local Open Scope ctype_scope.
+Section language.
+ Context {base_type_code : Type}.
+
+ Local Notation flat_type := (flat_type base_type_code).
+ Local Notation type := (type base_type_code).
+
+ Local Ltac rel_relb_t :=
+ repeat first [ progress simpl in *
+ | reflexivity
+ | intuition congruence
+ | setoid_rewrite Bool.andb_true_iff
+ | intro
+ | rewrite_hyp <- !* ].
+
+ Section flat_type.
+ Context {interp_base_type1 interp_base_type2 : base_type_code -> Type}.
+ Local Notation interp_flat_type1 := (interp_flat_type interp_base_type1).
+ Local Notation interp_flat_type2 := (interp_flat_type interp_base_type2).
+
+ Section gen_Prop.
+ Context (P : Type)
+ (and : P -> P -> P)
+ (True : P)
+ (False : P).
+ Section pointwise1.
+ Context (R : forall t, interp_base_type1 t -> P).
+ Fixpoint interp_flat_type_rel_pointwise1_gen_Prop (t : flat_type)
+ : interp_flat_type1 t -> P :=
+ match t with
+ | Tbase t => R t
+ | Unit => fun _ => True
+ | Prod A B => fun x : interp_flat_type _ A * interp_flat_type _ B
+ => and (interp_flat_type_rel_pointwise1_gen_Prop _ (fst x))
+ (interp_flat_type_rel_pointwise1_gen_Prop _ (snd x))
+ end.
+ End pointwise1.
+ Section pointwise2.
+ Context (R : forall t, interp_base_type1 t -> interp_base_type2 t -> P).
+ Fixpoint interp_flat_type_rel_pointwise_gen_Prop (t : flat_type)
+ : interp_flat_type1 t -> interp_flat_type2 t -> P :=
+ match t with
+ | Tbase t => R t
+ | Unit => fun _ _ => True
+ | Prod A B
+ => fun (x : interp_flat_type _ A * interp_flat_type _ B)
+ (y : interp_flat_type _ A * interp_flat_type _ B)
+ => and (interp_flat_type_rel_pointwise_gen_Prop _ (fst x) (fst y))
+ (interp_flat_type_rel_pointwise_gen_Prop _ (snd x) (snd y))
+ end.
+ End pointwise2.
+ Section pointwise2_hetero.
+ Context (R : forall t1 t2, interp_base_type1 t1 -> interp_base_type2 t2 -> P).
+ Fixpoint interp_flat_type_rel_pointwise_hetero_gen_Prop (t1 t2 : flat_type)
+ : interp_flat_type1 t1 -> interp_flat_type2 t2 -> P
+ := match t1, t2 with
+ | Tbase t1, Tbase t2 => R t1 t2
+ | Unit, Unit => fun _ _ => True
+ | Prod x1 y1, Prod x2 y2
+ => fun (a b : interp_flat_type _ _ * interp_flat_type _ _)
+ => and (interp_flat_type_rel_pointwise_hetero_gen_Prop x1 x2 (fst a) (fst b))
+ (interp_flat_type_rel_pointwise_hetero_gen_Prop y1 y2 (snd a) (snd b))
+ | Tbase _, _
+ | Unit, _
+ | Prod _ _, _
+ => fun _ _ => False
+ end.
+ End pointwise2_hetero.
+ End gen_Prop.
+
+ Definition interp_flat_type_relb_pointwise1
+ := @interp_flat_type_rel_pointwise1_gen_Prop bool andb true.
+ Global Arguments interp_flat_type_relb_pointwise1 _ !_ _ / .
+ Definition interp_flat_type_rel_pointwise1
+ := @interp_flat_type_rel_pointwise1_gen_Prop Prop and True.
+ Global Arguments interp_flat_type_rel_pointwise1 _ !_ _ / .
+ Lemma interp_flat_type_rel_pointwise1_iff_relb {R} t x
+ : interp_flat_type_relb_pointwise1 R t x <-> interp_flat_type_rel_pointwise1 R t x.
+ Proof using Type. clear; induction t; rel_relb_t. Qed.
+ Definition interp_flat_type_rel_pointwise1_gen_Prop_iff_bool
+ : forall {R} t x,
+ interp_flat_type_rel_pointwise1_gen_Prop bool _ _ R t x
+ <-> interp_flat_type_rel_pointwise1_gen_Prop Prop _ _ R t x
+ := @interp_flat_type_rel_pointwise1_iff_relb.
+ Definition interp_flat_type_relb_pointwise
+ := @interp_flat_type_rel_pointwise_gen_Prop bool andb true.
+ Global Arguments interp_flat_type_relb_pointwise _ !_ _ _ / .
+ Definition interp_flat_type_rel_pointwise
+ := @interp_flat_type_rel_pointwise_gen_Prop Prop and True.
+ Global Arguments interp_flat_type_rel_pointwise _ !_ _ _ / .
+ Lemma interp_flat_type_rel_pointwise_iff_relb {R} t x y
+ : interp_flat_type_relb_pointwise R t x y <-> interp_flat_type_rel_pointwise R t x y.
+ Proof using Type. clear; induction t; rel_relb_t. Qed.
+ Definition interp_flat_type_rel_pointwise_gen_Prop_iff_bool
+ : forall {R} t x y,
+ interp_flat_type_rel_pointwise_gen_Prop bool _ _ R t x y
+ <-> interp_flat_type_rel_pointwise_gen_Prop Prop _ _ R t x y
+ := @interp_flat_type_rel_pointwise_iff_relb.
+ Definition interp_flat_type_relb_pointwise_hetero
+ := @interp_flat_type_rel_pointwise_hetero_gen_Prop bool andb true false.
+ Global Arguments interp_flat_type_relb_pointwise_hetero _ !_ !_ _ _ / .
+ Definition interp_flat_type_rel_pointwise_hetero
+ := @interp_flat_type_rel_pointwise_hetero_gen_Prop Prop and True False.
+ Global Arguments interp_flat_type_rel_pointwise_hetero _ !_ !_ _ _ / .
+ Lemma interp_flat_type_rel_pointwise_hetero_iff_relb {R} t1 t2 x y
+ : interp_flat_type_relb_pointwise_hetero R t1 t2 x y <-> interp_flat_type_rel_pointwise_hetero R t1 t2 x y.
+ Proof using Type. clear; revert dependent t2; induction t1, t2; rel_relb_t. Qed.
+ Definition interp_flat_type_rel_pointwise_hetero_gen_Prop_iff_bool
+ : forall {R} t1 t2 x y,
+ interp_flat_type_rel_pointwise_hetero_gen_Prop bool _ _ _ R t1 t2 x y
+ <-> interp_flat_type_rel_pointwise_hetero_gen_Prop Prop _ _ _ R t1 t2 x y
+ := @interp_flat_type_rel_pointwise_hetero_iff_relb.
+
+ Lemma interp_flat_type_rel_pointwise_hetero_iff {R t} x y
+ : interp_flat_type_rel_pointwise (fun t => R t t) t x y
+ <-> interp_flat_type_rel_pointwise_hetero R t t x y.
+ Proof using Type. induction t; simpl; rewrite_hyp ?*; reflexivity. Qed.
+
+ Lemma interp_flat_type_rel_pointwise_impl {R1 R2 : forall t, _ -> _ -> Prop} t x y
+ : interp_flat_type_rel_pointwise (fun t x y => (R1 t x y -> R2 t x y)%type) t x y
+ -> (interp_flat_type_rel_pointwise R1 t x y
+ -> interp_flat_type_rel_pointwise R2 t x y).
+ Proof using Type. induction t; simpl; intuition. Qed.
+
+ Lemma interp_flat_type_rel_pointwise_always {R : forall t, _ -> _ -> Prop}
+ : (forall t x y, R t x y)
+ -> forall t x y, interp_flat_type_rel_pointwise R t x y.
+ Proof using Type. induction t; simpl; intuition. Qed.
+ End flat_type.
+ Section flat_type_extra.
+ Context {interp_base_type1 interp_base_type2 : base_type_code -> Type}.
+ Lemma interp_flat_type_rel_pointwise_impl' {R1 R2 : forall t, _ -> _ -> Prop} t x y
+ : @interp_flat_type_rel_pointwise
+ interp_base_type1 interp_base_type2
+ (fun t x y => (R1 t y x -> R2 t x y)%type) t x y
+ -> (interp_flat_type_rel_pointwise R1 t y x
+ -> interp_flat_type_rel_pointwise R2 t x y).
+ Proof using Type. induction t; simpl; intuition. Qed.
+
+ Global Instance interp_flat_type_rel_pointwise_Reflexive {R : forall t, _ -> _ -> Prop} {H : forall t, Reflexive (R t)}
+ : forall t, Reflexive (@interp_flat_type_rel_pointwise interp_base_type1 interp_base_type1 R t).
+ Proof using Type.
+ induction t; intro; simpl; try apply conj; try reflexivity.
+ Qed.
+
+ Lemma interp_flat_type_rel_pointwise_SmartVarfMap
+ {interp_base_type1' interp_base_type2'}
+ {R : forall t, _ -> _ -> Prop}
+ t f g x y
+ : @interp_flat_type_rel_pointwise interp_base_type1 interp_base_type2 R t (SmartVarfMap f x) (SmartVarfMap g y)
+ <-> @interp_flat_type_rel_pointwise interp_base_type1' interp_base_type2' (fun t x y => R t (f _ x) (g _ y)) t x y.
+ Proof using Type.
+ induction t; simpl; try reflexivity.
+ rewrite_hyp <- !*; reflexivity.
+ Qed.
+ End flat_type_extra.
+
+ Section type.
+ Section hetero.
+ Context (interp_src1 interp_src2 : flat_type -> Type)
+ (interp_dst1 interp_dst2 : flat_type -> Type).
+ Section hetero.
+ Context (Rsrc : forall t, interp_src1 t -> interp_src2 t -> Prop)
+ (Rdst : forall t, interp_dst1 t -> interp_dst2 t -> Prop).
+
+ Definition interp_type_gen_rel_pointwise_hetero (t : type)
+ : interp_type_gen_hetero interp_src1 interp_dst1 t
+ -> interp_type_gen_hetero interp_src2 interp_dst2 t
+ -> Prop
+ := @respectful_hetero _ _ _ _ (Rsrc _) (fun _ _ => Rdst _).
+ Global Arguments interp_type_gen_rel_pointwise_hetero _ _ _ / .
+ End hetero.
+ Section hetero_hetero.
+ Context (Rsrc : forall t1 t2, interp_src1 t1 -> interp_src2 t2 -> Prop)
+ (Rdst : forall t1 t2, interp_dst1 t1 -> interp_dst2 t2 -> Prop).
+
+ Fixpoint interp_type_gen_rel_pointwise_hetero_hetero (t1 t2 : type)
+ : interp_type_gen_hetero interp_src1 interp_dst1 t1
+ -> interp_type_gen_hetero interp_src2 interp_dst2 t2
+ -> Prop
+ := @respectful_hetero _ _ _ _ (Rsrc _ _) (fun _ _ => Rdst _ _).
+ Global Arguments interp_type_gen_rel_pointwise_hetero_hetero _ _ _ _ / .
+ End hetero_hetero.
+ End hetero.
+
+ Section partially_hetero.
+ Context (interp_flat_type1 interp_flat_type2 : flat_type -> Type)
+ (R : forall t, interp_flat_type1 t -> interp_flat_type2 t -> Prop).
+
+ Definition interp_type_gen_rel_pointwise
+ : forall t,
+ interp_type_gen interp_flat_type1 t
+ -> interp_type_gen interp_flat_type2 t
+ -> Prop
+ := interp_type_gen_rel_pointwise_hetero
+ interp_flat_type1 interp_flat_type2
+ interp_flat_type1 interp_flat_type2
+ R R.
+ Global Arguments interp_type_gen_rel_pointwise _ _ _ / .
+ End partially_hetero.
+ End type.
+
+ Section specialized_type.
+ Section hetero.
+ Context (interp_base_type1 interp_base_type2 : base_type_code -> Type).
+ Definition interp_type_rel_pointwise R
+ : forall t, interp_type interp_base_type1 t
+ -> interp_type interp_base_type2 t
+ -> Prop
+ := interp_type_gen_rel_pointwise _ _ (interp_flat_type_rel_pointwise R).
+ Global Arguments interp_type_rel_pointwise _ !_ _ _ / .
+
+ Definition interp_type_rel_pointwise_hetero R
+ : forall t1 t2, interp_type interp_base_type1 t1
+ -> interp_type interp_base_type2 t2
+ -> Prop
+ := interp_type_gen_rel_pointwise_hetero_hetero _ _ _ _ (interp_flat_type_rel_pointwise_hetero R) (interp_flat_type_rel_pointwise_hetero R).
+ Global Arguments interp_type_rel_pointwise_hetero _ !_ !_ _ _ / .
+ End hetero.
+ End specialized_type.
+
+ Section lifting.
+ Context {interp_base_type1 interp_base_type2 : base_type_code -> Type}.
+ Local Notation interp_flat_type1 := (interp_flat_type interp_base_type1).
+ Local Notation interp_flat_type2 := (interp_flat_type interp_base_type2).
+ Let Tbase := (@Tbase base_type_code).
+ Local Coercion Tbase : base_type_code >-> flat_type.
+
+ Section with_rel.
+ Context (R : forall t, interp_flat_type1 t -> interp_flat_type2 t -> Prop)
+ (RUnit : R Unit tt tt).
+ Section RProd.
+ Context (RProd : forall A B x y, R A (fst x) (fst y) /\ R B (snd x) (snd y) -> R (Prod A B) x y)
+ (RProd' : forall A B x y, R (Prod A B) x y -> R A (fst x) (fst y) /\ R B (snd x) (snd y)).
+ Lemma lift_interp_flat_type_rel_pointwise1 t (x : interp_flat_type1 t) (y : interp_flat_type2 t)
+ : interp_flat_type_rel_pointwise R t x y -> R t x y.
+ Proof using RProd RUnit. clear RProd'; induction t; simpl; destruct_head_hnf' unit; intuition. Qed.
+ Lemma lift_interp_flat_type_rel_pointwise2 t (x : interp_flat_type1 t) (y : interp_flat_type2 t)
+ : R t x y -> interp_flat_type_rel_pointwise R t x y.
+ Proof using RProd'. clear RProd; induction t; simpl; destruct_head_hnf' unit; split_and; intuition. Qed.
+ End RProd.
+ Section RProd_iff.
+ Context (RProd : forall A B x y, R A (fst x) (fst y) /\ R B (snd x) (snd y) <-> R (Prod A B) x y).
+ Lemma lift_interp_flat_type_rel_pointwise t (x : interp_flat_type1 t) (y : interp_flat_type2 t)
+ : interp_flat_type_rel_pointwise R t x y <-> R t x y.
+ Proof using RProd RUnit.
+ split_iff; split; auto using lift_interp_flat_type_rel_pointwise1, lift_interp_flat_type_rel_pointwise2.
+ Qed.
+ End RProd_iff.
+ End with_rel.
+ Lemma lift_interp_flat_type_rel_pointwise_f_eq {T} (f g : forall t, _ -> T t) t x y
+ : @interp_flat_type_rel_pointwise
+ interp_base_type1 interp_base_type2
+ (fun t x y => f t x = g t y)
+ t x y
+ <-> SmartVarfMap f x = SmartVarfMap g y.
+ Proof using Type.
+ induction t; unfold SmartVarfMap in *; simpl in *; destruct_head_hnf unit; try tauto.
+ rewrite_hyp !*; intuition congruence.
+ Qed.
+ Lemma lift_interp_flat_type_rel_pointwise_f_eq_id1 (f : forall t, _ -> _) t x y
+ : @interp_flat_type_rel_pointwise
+ interp_base_type1 interp_base_type2
+ (fun t x y => x = f t y)
+ t x y
+ <-> x = SmartVarfMap f y.
+ Proof using Type. rewrite lift_interp_flat_type_rel_pointwise_f_eq, SmartVarfMap_id; reflexivity. Qed.
+ Lemma lift_interp_flat_type_rel_pointwise_f_eq_id2 (f : forall t, _ -> _) t x y
+ : @interp_flat_type_rel_pointwise
+ interp_base_type1 interp_base_type2
+ (fun t x y => f t x = y)
+ t x y
+ <-> SmartVarfMap f x = y.
+ Proof using Type. rewrite lift_interp_flat_type_rel_pointwise_f_eq, SmartVarfMap_id; reflexivity. Qed.
+ Lemma lift_interp_flat_type_rel_pointwise_f_eq2 {T} (f g : forall t, _ -> _ -> T t) t x y
+ : @interp_flat_type_rel_pointwise
+ interp_base_type1 interp_base_type2
+ (fun t x y => f t x y = g t x y)
+ t x y
+ <-> SmartVarfMap2 f x y = SmartVarfMap2 g x y.
+ Proof using Type.
+ induction t; unfold SmartVarfMap2 in *; simpl in *; destruct_head_hnf unit; try tauto.
+ rewrite_hyp !*; intuition congruence.
+ Qed.
+ Lemma lift_interp_type_rel_pointwise_f_eq {T} (f g : forall t, _ -> T t) t x y
+ : interp_type_rel_pointwise
+ interp_base_type1 interp_base_type2
+ (fun t x y => f t x = g t y)
+ t x y
+ <-> (forall a b, SmartVarfMap f a = SmartVarfMap g b -> SmartVarfMap f (x a) = SmartVarfMap g (y b)).
+ Proof using Type.
+ destruct t; simpl; unfold interp_type_rel_pointwise, respectful_hetero.
+ setoid_rewrite lift_interp_flat_type_rel_pointwise_f_eq; reflexivity.
+ Qed.
+ Lemma lift_interp_type_rel_pointwise_f_eq_id1 (f : forall t, _ -> _) t x y
+ : interp_type_rel_pointwise
+ interp_base_type1 interp_base_type2
+ (fun t x y => x = f t y)
+ t x y
+ <-> (forall a, x (SmartVarfMap f a) = SmartVarfMap f (y a)).
+ Proof using Type. rewrite lift_interp_type_rel_pointwise_f_eq; setoid_rewrite SmartVarfMap_id; firstorder (subst; eauto). Qed.
+ Lemma lift_interp_type_rel_pointwise_f_eq_id2 (f : forall t, _ -> _) t x y
+ : interp_type_rel_pointwise
+ interp_base_type1 interp_base_type2
+ (fun t x y => f t x = y)
+ t x y
+ <-> (forall a, SmartVarfMap f (x a) = y (SmartVarfMap f a)).
+ Proof using Type. rewrite lift_interp_type_rel_pointwise_f_eq; setoid_rewrite SmartVarfMap_id; firstorder (subst; eauto). Qed.
+ End lifting.
+
+ Local Ltac t :=
+ repeat match goal with
+ | _ => intro
+ | [ H : False |- _ ] => exfalso; assumption
+ | _ => progress subst
+ | _ => assumption
+ | _ => progress inversion_sigma
+ | _ => progress inversion_prod
+ | _ => progress simpl in *
+ | _ => progress destruct_head_hnf' and
+ | [ H : context[List.In _ (_ ++ _)] |- _ ]
+ => rewrite List.in_app_iff in H
+ | _ => progress destruct_head' or
+ | _ => solve [ eauto ]
+ end.
+
+ Lemma interp_flat_type_rel_pointwise_flatten_binding_list
+ {interp_base_type1 interp_base_type2 t T} R' e1 e2 v1 v2
+ (H : List.In (existT _ t (v1, v2)%core) (flatten_binding_list e1 e2))
+ (HR : @interp_flat_type_rel_pointwise interp_base_type1 interp_base_type2 R' T e1 e2)
+ : R' t v1 v2.
+ Proof using Type. induction T; t. Qed.
+
+ Lemma interp_flat_type_rel_pointwise_hetero_flatten_binding_list2
+ {interp_base_type1 interp_base_type2 t1 t2 T1 T2} R' e1 e2 v1 v2
+ (H : List.In (existT _ (t1, t2)%core (v1, v2)%core) (flatten_binding_list2 e1 e2))
+ (HR : @interp_flat_type_rel_pointwise_hetero interp_base_type1 interp_base_type2 R' T1 T2 e1 e2)
+ : R' t1 t2 v1 v2.
+ Proof using Type.
+ revert dependent T2; induction T1, T2; t.
+ Qed.
+End language.
+
+Global Arguments interp_type_rel_pointwise {_ _ _} R {t} _ _.
+Global Arguments interp_type_rel_pointwise_hetero {_ _ _} R {t1 t2} _ _.
+Global Arguments interp_type_gen_rel_pointwise_hetero_hetero {_ _ _ _ _} Rsrc Rdst {t1 t2} _ _.
+Global Arguments interp_type_gen_rel_pointwise_hetero {_ _ _ _ _} Rsrc Rdst {t} _ _.
+Global Arguments interp_type_gen_rel_pointwise {_ _ _} R {t} _ _.
+Global Arguments interp_flat_type_rel_pointwise_gen_Prop {_ _ _ P} and True R {t} _ _.
+Global Arguments interp_flat_type_rel_pointwise_hetero_gen_Prop {_ _ _ P} and True False R {t1 t2} _ _.
+Global Arguments interp_flat_type_rel_pointwise_hetero {_ _ _} R {t1 t2} _ _.
+Global Arguments interp_flat_type_relb_pointwise_hetero {_ _ _} R {t1 t2} _ _.
+Global Arguments interp_flat_type_rel_pointwise1 {_ _} R {t} _.
+Global Arguments interp_flat_type_relb_pointwise1 {_ _} R {t} _.
+Global Arguments interp_flat_type_rel_pointwise {_ _ _} R {t} _ _.
+Global Arguments interp_flat_type_relb_pointwise {_ _ _} R {t} _ _.