aboutsummaryrefslogtreecommitdiff
path: root/src/Reflection/Z/Interpretations64/RelationsCombinations.v
diff options
context:
space:
mode:
Diffstat (limited to 'src/Reflection/Z/Interpretations64/RelationsCombinations.v')
-rw-r--r--src/Reflection/Z/Interpretations64/RelationsCombinations.v359
1 files changed, 359 insertions, 0 deletions
diff --git a/src/Reflection/Z/Interpretations64/RelationsCombinations.v b/src/Reflection/Z/Interpretations64/RelationsCombinations.v
new file mode 100644
index 000000000..b1287c7a7
--- /dev/null
+++ b/src/Reflection/Z/Interpretations64/RelationsCombinations.v
@@ -0,0 +1,359 @@
+Require Import Coq.ZArith.ZArith.
+Require Import Crypto.Reflection.Z.Syntax.
+Require Import Crypto.Reflection.Syntax.
+Require Import Crypto.Reflection.Application.
+Require Import Crypto.Reflection.Z.InterpretationsGen.
+Require Import Crypto.Reflection.Z.Interpretations64.
+Require Import Crypto.Reflection.Z.Interpretations64.Relations.
+Require Import Crypto.Util.Option.
+Require Import Crypto.Util.Bool.
+Require Import Crypto.Util.ZUtil.
+Require Import Crypto.Util.Prod.
+Require Import Crypto.Util.Tactics.
+
+Module Relations.
+ Section lift.
+ Context {interp_base_type1 interp_base_type2 : base_type -> Type}
+ (R : forall t, interp_base_type1 t -> interp_base_type2 t -> Prop).
+
+ Definition interp_type_rel_pointwise2_uncurried
+ {t : type base_type}
+ := match t return interp_type interp_base_type1 t -> interp_type interp_base_type2 t -> _ with
+ | Tflat T => fun f g => interp_flat_type_rel_pointwise2 (t:=T) R f g
+ | Arrow A B
+ => fun f g
+ => forall x y, interp_flat_type_rel_pointwise2 R x y
+ -> interp_flat_type_rel_pointwise2 R (ApplyInterpedAll f x) (ApplyInterpedAll g y)
+ end.
+
+ Lemma uncurry_interp_type_rel_pointwise2
+ {t f g}
+ : interp_type_rel_pointwise2 (t:=t) R f g
+ <-> interp_type_rel_pointwise2_uncurried (t:=t) f g.
+ Proof.
+ unfold interp_type_rel_pointwise2_uncurried.
+ induction t as [|A B IHt]; [ reflexivity | ].
+ { simpl; unfold Morphisms.respectful_hetero in *; destruct B.
+ { reflexivity. }
+ { setoid_rewrite IHt; clear IHt.
+ split; intro H; intros.
+ { simpl in *; intuition. }
+ { eapply (H (_, _) (_, _)); simpl in *; intuition. } } }
+ Qed.
+ End lift.
+
+ Section proj.
+ Context {interp_base_type1 interp_base_type2}
+ (proj : forall t : base_type, interp_base_type1 t -> interp_base_type2 t).
+
+ Let R {t : flat_type base_type} f g :=
+ SmartVarfMap (t:=t) proj f = g.
+
+ Definition interp_type_rel_pointwise2_uncurried_proj
+ {t : type base_type}
+ : interp_type interp_base_type1 t -> interp_type interp_base_type2 t -> Prop
+ := match t return interp_type interp_base_type1 t -> interp_type interp_base_type2 t -> Prop with
+ | Tflat T => @R _
+ | Arrow A B
+ => fun f g
+ => forall x : interp_flat_type interp_base_type1 (all_binders_for (Arrow A B)),
+ let y := SmartVarfMap proj x in
+ let fx := ApplyInterpedAll f x in
+ let gy := ApplyInterpedAll g y in
+ @R _ fx gy
+ end.
+
+ Lemma uncurry_interp_type_rel_pointwise2_proj
+ {t : type base_type}
+ {f : interp_type interp_base_type1 t}
+ {g}
+ : interp_type_rel_pointwise2 (t:=t) (fun t => @R _) f g
+ -> interp_type_rel_pointwise2_uncurried_proj (t:=t) f g.
+ Proof.
+ unfold interp_type_rel_pointwise2_uncurried_proj.
+ induction t as [t|A B IHt]; simpl; unfold Morphisms.respectful_hetero in *.
+ { induction t as [t|A IHA B IHB]; simpl; [ solve [ trivial | reflexivity ] | ].
+ intros [HA HB].
+ specialize (IHA _ _ HA); specialize (IHB _ _ HB).
+ unfold R in *.
+ repeat first [ progress destruct_head_hnf' prod
+ | progress simpl in *
+ | progress subst
+ | reflexivity ]. }
+ { destruct B; intros H ?; apply IHt, H; clear IHt;
+ repeat first [ reflexivity
+ | progress simpl in *
+ | progress unfold R, LiftOption.of' in *
+ | progress break_match ]. }
+ Qed.
+ End proj.
+
+ Section proj_option.
+ Context {interp_base_type1 : Type} {interp_base_type2 : base_type -> Type}
+ (proj_option : forall t, interp_base_type1 -> interp_base_type2 t).
+
+ Let R {t : flat_type base_type} f g :=
+ let f' := LiftOption.of' (t:=t) f in
+ match f' with
+ | Some f' => SmartVarfMap proj_option f' = g
+ | None => True
+ end.
+
+ Definition interp_type_rel_pointwise2_uncurried_proj_option
+ {t : type base_type}
+ : interp_type (LiftOption.interp_base_type' interp_base_type1) t -> interp_type interp_base_type2 t -> Prop
+ := match t return interp_type (LiftOption.interp_base_type' interp_base_type1) t -> interp_type interp_base_type2 t -> Prop with
+ | Tflat T => @R _
+ | Arrow A B
+ => fun f g
+ => forall x : interp_flat_type (fun _ => interp_base_type1) (all_binders_for (Arrow A B)),
+ let y := SmartVarfMap proj_option x in
+ let fx := ApplyInterpedAll f (LiftOption.to' (Some x)) in
+ let gy := ApplyInterpedAll g y in
+ @R _ fx gy
+ end.
+
+ Lemma uncurry_interp_type_rel_pointwise2_proj_option
+ {t : type base_type}
+ {f : interp_type (LiftOption.interp_base_type' interp_base_type1) t}
+ {g}
+ : interp_type_rel_pointwise2 (t:=t) (fun t => @R _) f g
+ -> interp_type_rel_pointwise2_uncurried_proj_option (t:=t) f g.
+ Proof.
+ unfold interp_type_rel_pointwise2_uncurried_proj_option.
+ induction t as [t|A B IHt]; simpl; unfold Morphisms.respectful_hetero in *.
+ { induction t as [t|A IHA B IHB]; simpl; [ solve [ trivial | reflexivity ] | ].
+ intros [HA HB].
+ specialize (IHA _ _ HA); specialize (IHB _ _ HB).
+ unfold R in *.
+ repeat first [ progress destruct_head_hnf' prod
+ | progress simpl in *
+ | progress unfold LiftOption.of' in *
+ | progress break_match
+ | progress break_match_hyps
+ | progress inversion_prod
+ | progress inversion_option
+ | reflexivity
+ | progress intuition subst ]. }
+ { destruct B; intros H ?; apply IHt, H; clear IHt.
+ { repeat first [ progress simpl in *
+ | progress unfold R, LiftOption.of' in *
+ | progress break_match
+ | reflexivity ]. }
+ { simpl in *; break_match; reflexivity. } }
+ Qed.
+ End proj_option.
+
+ Section proj_option2.
+ Context {interp_base_type1 : Type} {interp_base_type2 : Type}
+ (proj : interp_base_type1 -> interp_base_type2).
+
+ Let R {t : flat_type base_type} f g :=
+ let f' := LiftOption.of' (t:=t) f in
+ let g' := LiftOption.of' (t:=t) g in
+ match f', g' with
+ | Some f', Some g' => SmartVarfMap (fun _ => proj) f' = g'
+ | None, None => True
+ | Some _, _ => False
+ | None, _ => False
+ end.
+
+ Definition interp_type_rel_pointwise2_uncurried_proj_option2
+ {t : type base_type}
+ : interp_type (LiftOption.interp_base_type' interp_base_type1) t -> interp_type (LiftOption.interp_base_type' interp_base_type2) t -> Prop
+ := match t return interp_type (LiftOption.interp_base_type' interp_base_type1) t -> interp_type (LiftOption.interp_base_type' interp_base_type2) t -> Prop with
+ | Tflat T => @R _
+ | Arrow A B
+ => fun f g
+ => forall x : interp_flat_type (fun _ => interp_base_type1) (all_binders_for (Arrow A B)),
+ let y := SmartVarfMap (fun _ => proj) x in
+ let fx := ApplyInterpedAll f (LiftOption.to' (Some x)) in
+ let gy := ApplyInterpedAll g (LiftOption.to' (Some y)) in
+ @R _ fx gy
+ end.
+
+ Lemma uncurry_interp_type_rel_pointwise2_proj_option2
+ {t : type base_type}
+ {f : interp_type (LiftOption.interp_base_type' interp_base_type1) t}
+ {g : interp_type (LiftOption.interp_base_type' interp_base_type2) t}
+ : interp_type_rel_pointwise2 (t:=t) (fun t => @R _) f g
+ -> interp_type_rel_pointwise2_uncurried_proj_option2 (t:=t) f g.
+ Proof.
+ unfold interp_type_rel_pointwise2_uncurried_proj_option2.
+ induction t as [t|A B IHt]; simpl; unfold Morphisms.respectful_hetero in *.
+ { induction t as [t|A IHA B IHB]; simpl; [ solve [ trivial | reflexivity ] | ].
+ intros [HA HB].
+ specialize (IHA _ _ HA); specialize (IHB _ _ HB).
+ unfold R in *.
+ repeat first [ progress destruct_head_hnf' prod
+ | progress simpl in *
+ | progress unfold LiftOption.of' in *
+ | progress break_match
+ | progress break_match_hyps
+ | progress inversion_prod
+ | progress inversion_option
+ | reflexivity
+ | progress intuition subst ]. }
+ { destruct B; intros H ?; apply IHt, H; clear IHt.
+ { repeat first [ progress simpl in *
+ | progress unfold R, LiftOption.of' in *
+ | progress break_match
+ | reflexivity ]. }
+ { simpl in *; break_match; reflexivity. } }
+ Qed.
+ End proj_option2.
+
+ Section proj_from_option2.
+ Context {interp_base_type0 : Type} {interp_base_type1 interp_base_type2 : base_type -> Type}
+ (proj01 : forall t, interp_base_type0 -> interp_base_type1 t)
+ (proj02 : forall t, interp_base_type0 -> interp_base_type2 t)
+ (proj : forall t, interp_base_type1 t -> interp_base_type2 t).
+
+ Let R {t : flat_type base_type} f g :=
+ proj_eq_rel (SmartVarfMap proj (t:=t)) f g.
+
+ Definition interp_type_rel_pointwise2_uncurried_proj_from_option2
+ {t : type base_type}
+ : interp_type (LiftOption.interp_base_type' interp_base_type0) t -> interp_type interp_base_type1 t -> interp_type interp_base_type2 t -> Prop
+ := match t return interp_type _ t -> interp_type _ t -> interp_type _ t -> Prop with
+ | Tflat T => fun f0 f g => match LiftOption.of' f0 with
+ | Some _ => True
+ | None => False
+ end -> @R _ f g
+ | Arrow A B
+ => fun f0 f g
+ => forall x : interp_flat_type (fun _ => interp_base_type0) (all_binders_for (Arrow A B)),
+ let x' := SmartVarfMap proj01 x in
+ let y' := SmartVarfMap proj x' in
+ let fx := ApplyInterpedAll f x' in
+ let gy := ApplyInterpedAll g y' in
+ let f0x := LiftOption.of' (ApplyInterpedAll f0 (LiftOption.to' (Some x))) in
+ match f0x with
+ | Some _ => True
+ | None => False
+ end
+ -> @R _ fx gy
+ end.
+
+ Lemma uncurry_interp_type_rel_pointwise2_proj_from_option2
+ {t : type base_type}
+ {f0}
+ {f : interp_type interp_base_type1 t}
+ {g : interp_type interp_base_type2 t}
+ (proj012 : forall t x, proj t (proj01 t x) = proj02 t x)
+ : interp_type_rel_pointwise2 (t:=t) (LiftOption.lift_relation (fun t => proj_eq_rel (proj01 t))) f0 f
+ -> interp_type_rel_pointwise2 (t:=t) (LiftOption.lift_relation (fun t => proj_eq_rel (proj02 t))) f0 g
+ -> interp_type_rel_pointwise2_uncurried_proj_from_option2 (t:=t) f0 f g.
+ Proof.
+ unfold interp_type_rel_pointwise2_uncurried_proj_from_option2.
+ induction t as [t|A B IHt]; simpl; unfold Morphisms.respectful_hetero in *.
+ { induction t as [t|A IHA B IHB]; simpl.
+ { cbv [LiftOption.lift_relation proj_eq_rel R].
+ break_match; try tauto; intros; subst.
+ apply proj012. }
+ { intros [HA HB] [HA' HB'] Hrel.
+ specialize (IHA _ _ _ HA HA'); specialize (IHB _ _ _ HB HB').
+ unfold R, proj_eq_rel in *.
+ repeat first [ progress destruct_head_hnf' prod
+ | progress simpl in *
+ | progress unfold LiftOption.of' in *
+ | progress break_match
+ | progress break_match_hyps
+ | progress inversion_prod
+ | progress inversion_option
+ | reflexivity
+ | progress intuition subst ]. } }
+ { destruct B; intros H0 H1 ?; apply IHt; clear IHt; first [ apply H0 | apply H1 ];
+ repeat first [ progress simpl in *
+ | progress unfold R, LiftOption.of', proj_eq_rel, LiftOption.lift_relation in *
+ | break_match; rewrite <- ?proj012; reflexivity ]. }
+ Qed.
+ End proj_from_option2.
+ Global Arguments uncurry_interp_type_rel_pointwise2_proj_from_option2 {_ _ _ _ _} proj {t f0 f g} _ _ _.
+
+ Section proj1_from_option2.
+ Context {interp_base_type0 interp_base_type1 : Type} {interp_base_type2 : base_type -> Type}
+ (proj01 : interp_base_type0 -> interp_base_type1)
+ (proj02 : forall t, interp_base_type0 -> interp_base_type2 t)
+ (R : forall t, interp_base_type1 -> interp_base_type2 t -> Prop).
+
+ Definition interp_type_rel_pointwise2_uncurried_proj1_from_option2
+ {t : type base_type}
+ : interp_type (LiftOption.interp_base_type' interp_base_type0) t -> interp_type (LiftOption.interp_base_type' interp_base_type1) t -> interp_type interp_base_type2 t -> Prop
+ := match t return interp_type _ t -> interp_type _ t -> interp_type _ t -> Prop with
+ | Tflat T => fun f0 f g => match LiftOption.of' f0 with
+ | Some _ => True
+ | None => False
+ end -> match LiftOption.of' f with
+ | Some f' => interp_flat_type_rel_pointwise2 (@R) f' g
+ | None => True
+ end
+ | Arrow A B
+ => fun f0 f g
+ => forall x : interp_flat_type (fun _ => interp_base_type0) (all_binders_for (Arrow A B)),
+ let x' := SmartVarfMap (fun _ => proj01) x in
+ let y' := SmartVarfMap proj02 x in
+ let fx := LiftOption.of' (ApplyInterpedAll f (LiftOption.to' (Some x'))) in
+ let gy := ApplyInterpedAll g y' in
+ let f0x := LiftOption.of' (ApplyInterpedAll f0 (LiftOption.to' (Some x))) in
+ match f0x with
+ | Some _ => True
+ | None => False
+ end
+ -> match fx with
+ | Some fx' => interp_flat_type_rel_pointwise2 (@R) fx' gy
+ | None => True
+ end
+ end.
+
+ Lemma uncurry_interp_type_rel_pointwise2_proj1_from_option2
+ {t : type base_type}
+ {f0}
+ {f : interp_type (LiftOption.interp_base_type' interp_base_type1) t}
+ {g : interp_type interp_base_type2 t}
+ (proj012R : forall t x, @R _ (proj01 x) (proj02 t x))
+ : interp_type_rel_pointwise2 (t:=t) (LiftOption.lift_relation2 (proj_eq_rel proj01)) f0 f
+ -> interp_type_rel_pointwise2 (t:=t) (LiftOption.lift_relation (fun t => proj_eq_rel (proj02 t))) f0 g
+ -> interp_type_rel_pointwise2_uncurried_proj1_from_option2 (t:=t) f0 f g.
+ Proof.
+ unfold interp_type_rel_pointwise2_uncurried_proj1_from_option2.
+ induction t as [t|A B IHt]; simpl; unfold Morphisms.respectful_hetero in *.
+ { induction t as [t|A IHA B IHB]; simpl.
+ { cbv [LiftOption.lift_relation proj_eq_rel LiftOption.lift_relation2].
+ break_match; try tauto; intros; subst.
+ apply proj012R. }
+ { intros [HA HB] [HA' HB'] Hrel.
+ specialize (IHA _ _ _ HA HA'); specialize (IHB _ _ _ HB HB').
+ unfold proj_eq_rel in *.
+ repeat first [ progress destruct_head_hnf' prod
+ | progress simpl in *
+ | progress unfold LiftOption.of' in *
+ | progress break_match
+ | progress break_match_hyps
+ | progress inversion_prod
+ | progress inversion_option
+ | reflexivity
+ | progress intuition subst ]. } }
+ { destruct B; intros H0 H1 ?; apply IHt; clear IHt; first [ apply H0 | apply H1 ];
+ repeat first [ progress simpl in *
+ | progress unfold R, LiftOption.of', proj_eq_rel, LiftOption.lift_relation in *
+ | break_match; reflexivity ]. }
+ Qed.
+ End proj1_from_option2.
+ Global Arguments uncurry_interp_type_rel_pointwise2_proj1_from_option2 {_ _ _ _ _} R {t f0 f g} _ _ _.
+
+ Section combine_related.
+ Lemma related_flat_transitivity {interp_base_type1 interp_base_type2 interp_base_type3}
+ {R1 : forall t : base_type, interp_base_type1 t -> interp_base_type2 t -> Prop}
+ {R2 : forall t : base_type, interp_base_type1 t -> interp_base_type3 t -> Prop}
+ {R3 : forall t : base_type, interp_base_type2 t -> interp_base_type3 t -> Prop}
+ {t x y z}
+ : (forall t a b c, (R1 t a b : Prop) -> (R2 t a c : Prop) -> (R3 t b c : Prop))
+ -> interp_flat_type_rel_pointwise2 (t:=t) R1 x y
+ -> interp_flat_type_rel_pointwise2 (t:=t) R2 x z
+ -> interp_flat_type_rel_pointwise2 (t:=t) R3 y z.
+ Proof.
+ intro HRel; induction t; simpl; intuition eauto.
+ Qed.
+ End combine_related.
+End Relations.