Section SIM.
#[global]
Instance constant_symbols_sim : Similarity L.(constant_symbols) L'.(constant_symbols) :=
fun c : L.(constant_symbols) => fun c' : L'.(constant_symbols) => inl c = c'.
#[global]
Instance trm_sim : Similarity (trm L) (trm L') :=
trm_similarity_instance L.(function_symbols) L.(relation_symbols) L.(function_arity_table) L.(relation_arity_table) L.(constant_symbols) (L.(constant_symbols) + Henkin_constants) constant_symbols_sim.
#[global]
Instance trms_sim (n : nat) : Similarity (trms L n) (trms L' n) :=
trms_similarity_instance L.(function_symbols) L.(relation_symbols) L.(function_arity_table) L.(relation_arity_table) L.(constant_symbols) (L.(constant_symbols) + Henkin_constants) constant_symbols_sim n.
#[global]
Instance frm_sim : Similarity (frm L) (frm L') :=
frm_similarity_instance L.(function_symbols) L.(relation_symbols) L.(function_arity_table) L.(relation_arity_table) L.(constant_symbols) (L.(constant_symbols) + Henkin_constants) constant_symbols_sim.
#[global]
Instance frms_sim : Similarity (ensemble (frm L)) (ensemble (frm L')) :=
frms_similarity_instance L.(function_symbols) L.(relation_symbols) L.(function_arity_table) L.(relation_arity_table) L.(constant_symbols) (L.(constant_symbols) + Henkin_constants) constant_symbols_sim.
Fixpoint embed_trm (t : trm L) : trm L' :=
match t with
| Var_trm x => @Var_trm L' x
| Fun_trm f ts => @Fun_trm L' f (embed_trms ts)
| Con_trm c => @Con_trm L' (inl c)
end
with embed_trms {n : nat} (ts : trms L n) : trms L' n :=
match ts with
| O_trms => @O_trms L'
| S_trms n t ts => @S_trms L' n (embed_trm t) (embed_trms ts)
end.
Fixpoint embed_trm_graph (t' : trm L') : forall t : trm L, Prop :=
match t' with
| Var_trm x => fun t => @Var_trm L x = t
| Fun_trm f ts' => fun t => exists ts, embed_trms_graph ts' ts /\ @Fun_trm L f ts = t
| Con_trm c => fun t => match c with inl cc => @Con_trm L cc = t | inr hc => False end
end
with embed_trms_graph {n : nat} (ts' : trms L' n) : forall ts : trms L n, Prop :=
match ts' with
| O_trms => fun ts => O_trms = ts
| S_trms n t' ts' => fun ts => embed_trm_graph t' (head ts) /\ embed_trms_graph ts' (tail ts)
end.
Fixpoint embed_frm_graph (p' : frm L') : forall p : frm L, Prop :=
match p' with
| Rel_frm R ts' => fun p => exists ts, embed_trms_graph ts' ts /\ @Rel_frm L R ts = p
| Eqn_frm t1' t2' => fun p => exists t1, exists t2, embed_trm_graph t1' t1 /\ embed_trm_graph t2' t2 /\ @Eqn_frm L t1 t2 = p
| Neg_frm p1' => fun p => exists p1, embed_frm_graph p1' p1 /\ @Neg_frm L p1 = p
| Imp_frm p1' p2' => fun p => exists p1, exists p2, embed_frm_graph p1' p1 /\ embed_frm_graph p2' p2 /\ @Imp_frm L p1 p2 = p
| All_frm y p1' => fun p => exists p1, embed_frm_graph p1' p1 /\ @All_frm L y p1 = p
end.
#[local] Hint Rewrite embed_fvs_trm embed_fvs_trms : simplication_hints.
#[local] Hint Rewrite embed_fvs_frm : simplication_hints.
#[local] Hint Rewrite embed_subst_trm embed_subst_trms : simplication_hints.
#[local] Hint Rewrite embed_chi_frm : simplication_hints.
#[local] Hint Rewrite embed_trm_HC_free embed_trms_HC_free : simplication_hints.

Lemma embed_trm_inv (t' : trm L')
(HC_free : forall c, HC_occurs_in_trm c t' = false)
: exists t, embed_trm t = t'
with embed_trms_inv (n : nat) (ts' : trms L' n)
(HC_free : forall c, HC_occurs_in_trms c ts' = false)
: exists ts, embed_trms ts = ts'.