Set Implicit Arguments.
Unset Strict Implicit.
Set Maximal Implicit Insertion.
Section ILogicEmbed.
Context {A} `{ILOpsA: ILogicOps A}.
Context {B} `{ILOpsB: ILogicOps B}.
Class EmbedOp : Type := { embed : A -> B }.
Class Embed {EmbOp: EmbedOp} : Type := {
embed_sound p q : p |-- q -> embed p |-- embed q;
embedlforall T f : Forall x : T, embed (f x) -|- embed (Forall x : T, f x);
embedlexists T f : Exists x : T, embed (f x) -|- embed (Exists x : T, f x);
embedImpl a b : (embed a) -->> (embed b) -|- embed (a -->> b)
}.
End ILogicEmbed.
Arguments EmbedOp _ _ : clear implicits.
Arguments Embed _ {ILOpsA} _ {ILOpsB EmbOp} : rename.
Section ILogicEmbedOps.
Context {A B} `{HAB: Embed A B} {ILA: ILogic A} {ILB: ILogic B}.
Definition lembedand (a : A) (b : B) := (embed a) //\\ b.
Definition lembedimpl (a : A) (b : B) := (embed a) -->> b.
End ILogicEmbedOps.
Section ILEmbedId.
Context {A : Type} `{ILA : ILogic A}.
Instance EmbedOpId : EmbedOp A A := { embed := id }.
Global Instance EmbedId : Embed A A.
End ILEmbedId.
Section ILogicEmbedCompose.
Context {A B} `{HAB: Embed A B} {ILA: ILogic A} {ILB: ILogic B}.
Context {C} {HC: ILogicOps C} {HE: EmbedOp B C} {HBC : Embed B C} {ILC: ILogic C}.
Instance embedOpCompose : EmbedOp A C := { embed := fun x => embed (embed x) }.
Program Instance embedCompose : Embed A C.
Next Obligation.
do 2 apply embed_sound; assumption.
Qed.
Next Obligation.
split;
rewrite embedlforall; apply embed_sound; rewrite embedlforall; reflexivity.
Qed.
Next Obligation.
split;
rewrite embedlexists; apply embed_sound; rewrite embedlexists; reflexivity.
Qed.
Next Obligation.
split;
rewrite embedImpl; apply embed_sound; rewrite embedImpl; reflexivity.
Qed.
End ILogicEmbedCompose.
Infix "/\\" := lembedand (at level 75, right associativity).
Infix "->>" := lembedimpl (at level 77, right associativity).
Section ILogicEmbedFacts.
Context {A B} `{HAB: Embed A B} {ILA: ILogic A} {ILB: ILogic B}.
Global Instance embed_lentails_m :
Proper (lentails ==> lentails) embed.
Global Instance embed_lequiv_m :
Proper (lequiv ==> lequiv) embed.
Global Instance lembedimpl_lentails_m:
Proper (lentails --> lentails ++> lentails) lembedimpl.
Global Instance lembedimpl_lequiv_m:
Proper (lequiv ==> lequiv ==> lequiv) lembedimpl.
Global Instance lembedand_lentails_m:
Proper (lentails ==> lentails ==> lentails) lembedand.
Global Instance lembedand_lequiv_m:
Proper (lequiv ==> lequiv ==> lequiv) lembedand.

(* Specifications: *)
Lemma embedland a b : embed a //\\ embed b -|- embed (a //\\ b).
Lemma embedlor a b : embed a \\// embed b -|- embed (a \\// b).
Lemma embedlfalse : embed lfalse -|- lfalse.
Lemma embedltrue : embed ltrue -|- ltrue.
Lemma embedlandC (P R : B) (Q : A) : P //\\ Q /\\ R -|- Q /\\ P //\\ R.
Lemma embedlimplC (P R : B) (Q : A) : P -->> Q ->> R -|- Q ->> P -->> R.
Lemma limpllandC (P Q R : B) : P //\\ (Q -->> R) |-- Q -->> P //\\ R.
Lemma embed_existsL (P : A) : Exists x : |-- P, ltrue |-- embed P.
End ILogicEmbedFacts.