(** ** Soundness *)
Definition cast {domain} (eta eta' : nat -> domain) (I : interp eta) : interp eta'.
destruct I; econstructor; eauto.
Defined.

(* Specifications: *)
Lemma eval_ext_p t dom rho rho' eta eta' (I : interp dom eta) :
(forall v, v el vars_t t -> rho v = rho' v) ->
(forall p, p el consts_t t -> eta p = eta' p) ->
@eval _ _ I rho t = @eval _ _ (cast eta' I) rho' t.
Lemma eval_ext t dom rho rho' eta (I : interp dom eta) :
(forall v, v el vars_t t -> rho v = rho' v) -> eval rho t = eval rho' t.
Lemma sat_ext_p b (phi : form b) dom rho rho' eta eta' (I : interp dom eta) :
(forall v, rho v = rho' v) ->
(forall p, p el consts phi -> eta p = eta' p) ->
sat I rho phi <-> sat (cast eta' I) rho' phi.
Lemma sat_ext b (phi : form b) dom rho rho' eta (I : interp dom eta) :
sat I rho phi -> (forall v, rho v = rho' v) -> sat I rho' phi.
Lemma sat_ext_p_list b (A : list (form b)) dom rho rho' eta eta' (I : interp dom eta) :
(forall v, rho v = rho' v) ->
(forall p, p el consts_l A -> eta p = eta' p) ->
(forall phi, phi el A -> sat I rho phi) <-> (forall phi, phi el A -> sat (cast eta' I) rho' phi).
Lemma eval_empty t dom eta (I : interp dom eta) rho rho' :
vars_t t = [] -> eval rho t = eval rho' t.
Lemma subst_eval dom eta (I : interp dom eta) rho x t t' :
eval rho (subst_t x t' t) = eval (rho [[x:=eval rho t']]) t.
Lemma subst_sat b (phi : form b) dom eta (I : interp dom eta) rho x t :
vars_t t = [] -> sat I rho (subst x t phi) <-> sat I (rho [[x:=eval rho t]]) phi.
Lemma substconst_sat b (phi : form b) dom eta rho x a d (I : interp dom eta) :
fresh a (consts phi) ->
sat (eta [[a := d]]) (cast _ I) rho (subst x (P a) phi) <->
sat eta I (rho [[ x := d ]]) phi.
Lemma soundness' {b} A (phi : form b) :
A ⊢I phi -> valid (A ==> phi).
Theorem soundness {b} (phi : form b) :
nil ⊢I phi -> valid phi.