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.

Lemma embedlandC (P R : B) (Q : A) : P //\\ Q /\\ R -|- Q /\\ P //\\ R.