cpsa-4.4.6: coq/Subst.v
(* Substitition
Copyright (c) 2021 The MITRE Corporation
This program is free software: you can redistribute it and/or
modify it under the terms of the BSD License as published by the
University of California. *)
(** * Substitition
This library is a companion to the [Match] library. It provides a
substitution function [subst_term] such that when [match_term]
matches [x] to [y] and produces substitution [sb], then
[subst_term sb x] equals [y]. *)
From Stdlib Require Import FunInd String List Nat Bool Arith.
Require Import Preamble Monad Alg Match.
Definition subst_skey (sb: sbst) (x: skey): skey :=
match x with
| Sv v =>
match lookup v sb with
| Some (Sk y) => y
| _ => x
end
| Lt u v =>
let x :=
match lookup u sb with
| Some (Nm x) => x
| _ => u
end in
let y :=
match lookup v sb with
| Some (Nm y) => y
| _ => v
end in
Lt x y
end.
Definition subst_akey (sb: sbst) (x: akey): alg :=
match x with
| Av v =>
match lookup v sb with
| Some (Ak y) => Ak y
| Some (Ik y) => Ik y
| _ => Ak x
end
| Pb v =>
match lookup v sb with
| Some (Nm u) => Ak (Pb u)
| _ => Ak x
end
| Pb2 s v =>
match lookup v sb with
| Some (Nm u) => Ak (Pb2 s u)
| _ => Ak x
end
end.
(** Definition of substitution *)
Fixpoint subst_term (sb: sbst) (x: alg): alg :=
match x with
| Tx v =>
match lookup v sb with
| Some (Tx u) => Tx u
| _ => x
end
| Dt v =>
match lookup v sb with
| Some (Dt u) => Dt u
| _ => x
end
| Nm v =>
match lookup v sb with
| Some (Nm u) => Nm u
| _ => x
end
| Sk x => Sk (subst_skey sb x)
| Ak x => subst_akey sb x
| Ik x => inv (subst_akey sb x)
| Ch v =>
match lookup v sb with
| Some (Ch u) => Ch u
| _ => x
end
| Mg v =>
match lookup v sb with
| Some y => y
| None => x
end
| Tg s => x
| Pr x y => Pr (subst_term sb x) (subst_term sb y)
| En x y => En (subst_term sb x) (subst_term sb y)
| Hs x => Hs (subst_term sb x)
end.
(** ** Correctness of Substitution *)
Lemma extend_term_lookup:
forall (sb sb': sbst) (v: var) (x: alg),
extend_term sb v x = Some sb' ->
lookup v sb' = Some x.
Proof.
unfold extend_term.
intros.
alt_option_dec (lookup v sb) b G;
rewrite G in H.
- inv H; simpl; auto.
rewrite Nat.eqb_refl; simpl; auto.
- destruct (alg_dec x b); inv H; simpl; auto.
Qed.
Lemma lookup_extend_term_lookup:
forall v x y z sb sb',
lookup v sb = Some x ->
extend_term sb y z = Some sb' ->
lookup v sb' = Some x.
Proof.
intros.
unfold extend_term in H0.
destruct (Nat.eq_dec y v) as [G|G]; subst.
- rewrite H in H0.
destruct (alg_dec z x) as [G|G]; subst; inv H0; auto.
- alt_option_dec (lookup y sb) b F;
rewrite F in H0.
+ inv H0; simpl.
rewrite <- Nat.eqb_neq in G.
rewrite G; auto.
+ destruct (alg_dec z b); subst.
inv H0; auto.
inv H0.
Qed.
Lemma lookup_match_skey_lookup:
forall v x y z sb sb',
lookup v sb = Some x ->
match_skey sb y z = Some sb' ->
lookup v sb' = Some x.
Proof.
intros.
unfold match_skey in H0.
destruct y.
- eapply lookup_extend_term_lookup in H0; eauto.
- destruct z.
+ inv H0.
+ apply do_some in H0.
repeat destruct_ex_and.
eapply lookup_extend_term_lookup in H0; eauto.
eapply lookup_extend_term_lookup in H1; eauto.
Qed.
Lemma lookup_match_akey_lookup:
forall v x y z sb sb',
lookup v sb = Some x ->
match_akey sb y z = Some sb' ->
lookup v sb' = Some x.
Proof.
intros.
unfold match_akey in H0.
destruct y.
- eapply lookup_extend_term_lookup in H0; eauto.
- destruct z.
+ inv H0.
+ eapply lookup_extend_term_lookup in H0; eauto.
+ inv H0.
- destruct z.
+ inv H0.
+ inv H0.
+ destruct (String.eqb_spec s s0); subst.
* eapply lookup_extend_term_lookup in H; eauto.
* inv H.
inv H0.
Qed.
Functional Scheme match_term_ind :=
Induction for match_term Sort Prop.
Lemma lookup_match_term_lookup:
forall v x y z sb sb',
lookup v sb = Some x ->
match_term sb y z = Some sb' ->
lookup v sb' = Some x.
Proof.
intros.
revert H0.
revert H.
revert sb'.
revert x.
revert v.
functional induction (match_term sb y z); intros;
try match goal with
| [ H: None = Some _ |- _ ] => inv H
| [ H: extend_term _ _ _ = Some _ |- _ ] =>
eapply lookup_extend_term_lookup in H; eauto
| [ H: match_skey _ _ _ = Some _ |- _ ] =>
eapply lookup_match_skey_lookup in H; eauto
| [ H: match_akey _ _ _ = Some _ |- _ ] =>
eapply lookup_match_akey_lookup in H; eauto
end.
- inv H0; auto.
- eapply IHo0; eauto.
- eapply IHo0; eauto.
- eapply IHo; eauto.
Qed.
Lemma match_match_subst_skey:
forall w x y z sb sb' sb'',
match_skey sb w y = Some sb' ->
match_term sb' x z = Some sb'' ->
subst_skey sb'' w = y.
Proof.
intros.
unfold match_skey in H.
destruct w.
- apply extend_term_lookup in H.
eapply lookup_match_term_lookup in H; eauto.
simpl; rewrite H; auto.
- destruct y.
* inv H.
* apply do_some in H.
repeat destruct_ex_and.
apply extend_term_lookup in H.
eapply lookup_extend_term_lookup in H; eauto.
eapply lookup_match_term_lookup in H; eauto.
apply extend_term_lookup in H1.
eapply lookup_match_term_lookup in H1; eauto.
simpl.
rewrite H.
rewrite H1; auto.
Qed.
Lemma match_match_subst_akey:
forall w x y z sb sb' sb'',
match_akey sb w y = Some sb' ->
match_term sb' x z = Some sb'' ->
subst_akey sb'' w = (Ak y).
Proof.
intros.
unfold match_akey in H.
destruct w.
- apply extend_term_lookup in H.
eapply lookup_match_term_lookup in H; eauto.
simpl; rewrite H; auto.
- destruct y.
* inv H.
* apply extend_term_lookup in H.
eapply lookup_match_term_lookup in H; eauto.
simpl.
rewrite H; auto.
* inv H.
- destruct y.
* inv H.
* inv H.
* destruct (String.eqb_spec s s0); subst.
-- apply extend_term_lookup in H.
eapply lookup_match_term_lookup in H; eauto.
simpl.
rewrite H; auto.
-- inv H.
Qed.
(** The proof of this lemma contains two tricky steps. *)
Lemma match_match_subst_term:
forall w x y z sb sb' sb'',
match_term sb w y = Some sb' ->
match_term sb' x z = Some sb'' ->
subst_term sb'' w = y.
Proof.
intros w x y z sb sb' sb''.
revert sb'.
revert z.
revert x.
functional induction (match_term sb w y); intros; simpl;
try match goal with
| [ H: None = Some _ |- _ ] => inv H
| [ H: extend_term _ _ _ = Some _ |- _ ] =>
apply extend_term_lookup in H;
eapply lookup_match_term_lookup in H; eauto;
match goal with
| [ H: lookup _ _ = Some _ |- _ ] =>
rewrite H; simpl; auto
end
| [ H: match_akey _ _ _ = Some _ |- _ ] =>
eapply match_match_subst_akey in H; eauto;
match goal with
| [ H: lookup _ _ = Some _ |- _ ] =>
rewrite H; simpl; auto
end
end.
- eapply match_match_subst_skey in H; eauto.
rewrite H; auto.
- eapply match_match_subst_akey in H; eauto.
simpl in H.
apply eq_sym.
rewrite inv_swap.
simpl; auto.
- eapply match_match_subst_akey in H; eauto.
simpl in H.
apply eq_sym.
rewrite inv_swap.
simpl; auto.
- eapply match_match_subst_akey in H; eauto.
simpl in H.
apply eq_sym.
rewrite inv_swap.
simpl; auto.
- rewrite String.eqb_eq in e1; subst; auto.
- (* This in the tricky part *)
apply IHo with (x := Pr w x)(z := Pr y0 z) in e1; auto.
+ eapply IHo0 in H; eauto.
rewrite H.
rewrite e1; auto.
+ simpl; auto.
rewrite H; auto.
- (* This in the tricky part *)
apply IHo with (x := En w x)(z := En y0 z) in e1; auto.
+ eapply IHo0 in H; eauto.
rewrite H.
rewrite e1; auto.
+ simpl; auto.
rewrite H; auto.
- eapply IHo in H; eauto.
rewrite H; auto.
Qed.
Lemma match_subst_skey:
forall x y sb sb',
match_skey sb x y = Some sb' ->
subst_skey sb' x = y.
Proof.
intros.
unfold match_skey in H.
unfold subst_skey.
destruct x; simpl in *; auto.
- apply extend_term_lookup in H.
rewrite H; auto.
- destruct y; simpl in *; auto.
+ inv H.
+ apply do_some in H.
repeat destruct_ex_and.
apply extend_term_lookup in H.
eapply lookup_extend_term_lookup in H; eauto.
apply extend_term_lookup in H0.
rewrite H0.
rewrite H; auto.
Qed.
Lemma match_subst_akey:
forall x y sb sb',
match_akey sb x y = Some sb' ->
subst_akey sb' x = Ak y.
Proof.
intros.
unfold match_akey in H.
unfold subst_akey.
destruct x; simpl in *; auto.
- apply extend_term_lookup in H.
rewrite H; auto.
- destruct y; simpl in *; auto.
+ inv H.
+ apply extend_term_lookup in H.
rewrite H; auto.
+ inv H.
- destruct y; simpl in *; auto.
+ inv H.
+ inv H.
+ destruct (String.eqb_spec s s0); subst.
apply extend_term_lookup in H.
rewrite H; auto.
inv H.
Qed.
(** The main correctness theorem *)
Theorem match_subst_term:
forall x y sb sb',
match_term sb x y = Some sb' ->
subst_term sb' x = y.
Proof.
intros x y sb.
functional induction (match_term sb x y); intros;
try match goal with
| [ H: None = Some _ |- _ ] => inv H
| [ H: extend_term _ _ _ = Some _ |- _ ] =>
apply extend_term_lookup in H;
simpl; rewrite H; auto
| [ H: match_skey _ _ _ = Some _ |- _ ] =>
apply match_subst_skey in H;
simpl; rewrite H; auto
| [ H: match_akey _ _ _ = Some _ |- _ ] =>
apply match_subst_akey in H;
unfold subst_akey in H;
simpl; rewrite H; auto
end.
- apply String.eqb_eq in e1; subst.
simpl; auto.
- simpl.
pose proof H as G.
eapply match_match_subst_term in H; eauto.
apply IHo0 in G.
rewrite G.
rewrite H; auto.
- simpl.
pose proof H as G.
eapply match_match_subst_term in H; eauto.
apply IHo0 in G.
rewrite G.
rewrite H; auto.
- simpl.
apply IHo in H; auto.
rewrite H; auto.
Qed.