Theory Term_Rewriting

theory Term_Rewriting
imports Subterm_and_Context Relation_Closure
(*
Author:  Christian Sternagel <c.sternagel@gmail.com>
Author:  René Thiemann <rene.thiemann@uibk.ac.at>
License: LGPL (see file COPYING.LESSER)
*)
chapter ‹Term Rewriting›

theory Term_Rewriting
  imports
    Knuth_Bendix_Order.Subterm_and_Context
    Relation_Closure
begin


text ‹
  A rewrite rule is a pair of terms. A term rewrite system (TRS) is a set of rewrite rules.
›
type_synonym ('f, 'v) rule = "('f, 'v) term × ('f, 'v) term"
type_synonym ('f, 'v) trs  = "('f, 'v) rule set"

inductive_set rstep :: "_ ⇒ ('f, 'v) term rel" for R :: "('f, 'v) trs"
  where
    rstep: "⋀C σ l r. (l, r) ∈ R ⟹ s = C⟨l ⋅ σ⟩ ⟹ t = C⟨r ⋅ σ⟩ ⟹ (s, t) ∈ rstep R"

lemma rstep_induct_rule [case_names IH, induct set: rstep]:
  assumes "(s, t) ∈ rstep R"
    and "⋀C σ l r. (l, r) ∈ R ⟹ P (C⟨l ⋅ σ⟩) (C⟨r ⋅ σ⟩)"
  shows "P s t"
  using assms by (induct) simp

text ‹
  An alternative induction scheme that treats the rule-case, the
  substition-case, and the context-case separately.
›
lemma rstep_induct [consumes 1, case_names rule subst ctxt]:
  assumes "(s, t) ∈ rstep R"
    and rule: "⋀l r. (l, r) ∈ R ⟹ P l r"
    and subst: "⋀s t σ. P s t ⟹ P (s ⋅ σ) (t ⋅ σ)"
    and ctxt: "⋀s t C. P s t ⟹ P (C⟨s⟩) (C⟨t⟩)"
  shows "P s t"
  using assms by (induct) auto


lemmas rstepI = rstep.intros [intro]

lemmas rstepE = rstep.cases [elim]

lemma rstep_ctxt [intro]: "(s, t) ∈ rstep R ⟹ (C⟨s⟩, C⟨t⟩) ∈ rstep R"
  by (force simp flip: ctxt_ctxt_compose)

lemma rstep_rule [intro]: "(l, r) ∈ R ⟹ (l, r) ∈ rstep R"
  using rstep.rstep [where C =  and σ = Var and R = R] by simp

lemma rstep_subst [intro]: "(s, t) ∈ rstep R ⟹ (s ⋅ σ, t ⋅ σ) ∈ rstep R"
  by (force simp flip: subst_subst_compose)

lemma rstep_empty [simp]: "rstep {} = {}"
  by auto

lemma rstep_mono: "R ⊆ S ⟹ rstep R ⊆ rstep S"
  by force

lemma rstep_union: "rstep (R ∪ S) = rstep R ∪ rstep S"
  by auto

lemma rstep_converse [simp]: "rstep (R¯) = (rstep R)¯"
  by auto

interpretation subst: rel_closure "λσ t. t ⋅ σ" Var "λx y. y ∘s x" by (standard) auto
declare subst.closure.induct [consumes 1, case_names subst, induct pred: subst.closure]
declare subst.closure.cases [consumes 1, case_names subst, cases pred: subst.closure]

interpretation ctxt: rel_closure "ctxt_apply_term"  "(∘c)" by (standard) auto
declare ctxt.closure.induct [consumes 1, case_names ctxt, induct pred: ctxt.closure]
declare ctxt.closure.cases [consumes 1, case_names ctxt, cases pred: ctxt.closure]

lemma rstep_eq_closure: "rstep R = ctxt.closure (subst.closure R)"
  by (force elim: ctxt.closure.cases subst.closure.cases)

lemma ctxt_closed_rstep [intro]: "ctxt.closed (rstep R)"
  by (simp add: rstep_eq_closure ctxt.closed_closure)

lemma ctxt_closed_one:
  "ctxt.closed r ⟹ (s, t) ∈ r ⟹ (Fun f (ss @ s # ts), Fun f (ss @ t # ts)) ∈ r"
  using ctxt.closedD [of r s t "More f ss □ ts"] by auto

lemma args_steps_imp_steps:
  assumes "ctxt.closed r"
    and len: "length ts = length us"
    and "∀i < length us. (ts ! i, us ! i) ∈ r*"
  shows "(Fun f ts, Fun f us) ∈ r*"
proof -
  have "(Fun f ts, Fun f (take i us @ drop i ts)) ∈ r*" if "i ≤ length us" for i
    using that
  proof (induct i)
    case (Suc i)
    then have "(Fun f ts, Fun f (take i us @ drop i ts)) ∈ r*" by simp
    moreover have "take i us @ drop i ts = take i us @ ts ! length (take i us) # drop (Suc i) ts"
      using Suc and len by (auto simp: Cons_nth_drop_Suc min_def)
    moreover have "take (Suc i) us @ drop (Suc i) ts = take i us @ us ! length (take i us) # drop (Suc i) ts"
      using Suc and len by (auto simp: min_def take_Suc_conv_app_nth)
    moreover have "(Fun f (take i us @ ts ! length (take i us) # drop (Suc i) ts),
    Fun f (take i us @ us ! length (take i us) # drop (Suc i) ts)) ∈ r*"
      using assms and Suc by (intro ctxt_closed_one) auto
    ultimately show ?case by simp
  qed simp
  note this [of "length us"] and len
  then show ?thesis by simp
qed

end