theory Ordered_Algebra
imports
Quasi_Order
HOL.Lattices
begin
section {* F-Algebras *}
locale algebra = fixes I :: "'f ⇒ 'a list ⇒ 'a"
begin
fun eval :: "('f,'v) term ⇒ ('v ⇒ 'a) ⇒ 'a"
where "eval (Var x) α = α x"
| "eval (Fun f ss) α = I f (map (λs. eval s α) ss)"
notation eval ("⟦(_)⟧")
lemma eval_same_vars[intro]: "(⋀x. x ∈ vars_term t ⟹ α x = β x) ⟹ ⟦t⟧ α = ⟦t⟧ β"
by(induct t, auto intro!:map_cong[OF refl] cong[of "I _"])
lemma subset_range_eval: "range α ⊆ range (λs. ⟦s⟧α)" (is "?l ⊆ ?r")
proof
fix a assume "a ∈ ?l"
then obtain v where "α v = a" by auto
then show "a ∈ ?r" by (auto intro!: range_eqI[of _ _ "Var v"])
qed
definition constant_at where "constant_at f n i ≡
∀as b. i < n ⟶ length as = n ⟶ I f (as[i:=b]) = I f as"
lemma constant_atI:
assumes "⋀as b. i < n ⟹ length as = n ⟹ I f (as[i:=b]) = I f as"
shows "constant_at f n i" using assms by (auto simp: constant_at_def)
lemma constant_atD:
"constant_at f n i ⟹ length as = n ⟹ I f (as[i:=b]) = I f as"
by (auto simp: constant_at_def)
definition "constant_term_on s x ≡ ∀α a. ⟦s⟧(α(x:=a)) = ⟦s⟧α"
lemma constant_term_onI: assumes "⋀α a. ⟦s⟧(α(x:=a)) = ⟦s⟧α" shows "constant_term_on s x"
using assms by (auto simp: constant_term_on_def)
lemma constant_term_onD:
assumes "constant_term_on s x" shows "⟦s⟧(α(x:=a)) = ⟦s⟧α"
using assms by (auto simp: constant_term_on_def)
lemma constant_term_onE:
assumes "constant_term_on s x" and "(⋀α a. ⟦s⟧(α(x:=a)) = ⟦s⟧α) ⟹ thesis"
shows thesis using assms by (auto simp: constant_term_on_def)
lemma constant_term_on_extra_var: "x ∉ vars_term s ⟹ constant_term_on s x"
by (auto intro!: constant_term_onI)
lemma constant_term_on_eq:
assumes "⟦s⟧ = ⟦t⟧" and "constant_term_on s x" shows "constant_term_on t x"
using assms by (simp add: constant_term_on_def)
definition "constant_term s ≡ ∀x. constant_term_on s x"
lemma constant_termI: assumes "⋀x. constant_term_on s x" shows "constant_term s"
using assms by (auto simp: constant_term_def)
lemma ground_imp_constant: "ground s ⟹ constant_term s"
by (auto intro!: constant_termI constant_term_on_extra_var simp: ground_vars_term_empty)
end
declare algebra.eval.simps[code,simp]
lemma eval_map_term:
"algebra.eval I (map_term ff fv t) α = algebra.eval (I ∘ ff) t (α ∘ fv)"
by (induct t, auto intro: cong[of "I _"])
text {* In the term algebra, evaluation is substitution. *}
interpretation term_algebra: algebra Fun
rewrites term_algebra_eval: "term_algebra.eval = op ⋅"
proof (intro ext)
show "algebra.eval Fun s σ = s⋅σ" for s σ by (induct s, unfold algebra.eval.simps, auto)
qed
subsection {* Homomorphism *}
locale algebra_hom = source: algebra I + target: algebra I'
for hom :: "'a ⇒ 'b" and I :: "'f ⇒ 'a list ⇒ 'a" and I' :: "'f ⇒ 'b list ⇒ 'b" +
assumes hom: "⋀f as. hom (I f as) = I' f (map hom as)"
begin
lemma hom_eval: "hom (source.eval s α) = target.eval s (λx. hom (α x))"
by (induct s, auto simp: hom intro: arg_cong[OF list.map_cong0])
end
context algebra begin
text {* Evaluation is a homomophism from the term algebra. *}
sublocale eval_hom: algebra_hom "(λs. ⟦s⟧α)" Fun I
rewrites "algebra.eval Fun = op ⋅"
by (unfold_locales, auto simp: term_algebra_eval)
lemmas subst_eval = eval_hom.hom_eval
end
thm term_algebra.subst_eval[folded subst_compose_def]
locale algebra_epim = algebra_hom +
assumes surj: "surj hom"
text {* An algebra where every element has a representation: *}
locale algebra_constant = algebra I
for I :: "'f ⇒ 'a list ⇒ 'a"
and const :: "'a ⇒ ('f,'v) term" +
assumes var_term_const[simp]: "⋀d. vars_term (const d) = {}"
and eval_const[simp]: "⋀d α. ⟦const d⟧ α = d"
subsection {* Quasi-Ordered Algebras *}
text
{* A quasi-ordered algebra is an F-algebra whose domain is quasi-ordered.
We cannot use @{class quasi_order} as a class since later we want to use
arbitrary order on terms which cannot be globally fixed. Local instantiation
would alleviate the problem.
*}
text {* Following is a syntactic locale where executable definitions should be made. *}
locale ord_algebra = ord less_eq less + algebra I
for less_eq less :: "'a ⇒ 'a ⇒ bool"
and I :: "'f ⇒ 'a list ⇒ 'a"
begin
interpretation ord_syntax.
text{* Base orderings are extended over terms in the standard way. *}
definition less_term (infix "⊏⇩t" 50) where "s ⊏⇩t t ≡ ∀α. ⟦s⟧α ⊏ ⟦t⟧α"
notation less_term (infix "⊏⇩t" 50)
definition less_eq_term (infix "⊑⇩t" 50) where "s ⊑⇩t t ≡ ∀α. ⟦s⟧α ⊑ ⟦t⟧α"
notation less_eq_term (infix "⊑⇩t" 50)
lemma less_termI[intro]: "(⋀α :: 'v ⇒ 'a. ⟦s⟧α ⊏ ⟦t⟧α) ⟹ s ⊏⇩t t" by (auto simp: less_term_def)
lemma less_termE[elim]:
assumes "s ⊏⇩t t" and "(⋀α :: 'v ⇒ 'a. ⟦s⟧α ⊏ ⟦t⟧α) ⟹ thesis"
shows "thesis" using assms by (auto simp: less_term_def)
lemma less_eq_termI[intro]: "(⋀α :: 'v ⇒ 'a. ⟦s⟧α ⊑ ⟦t⟧α) ⟹ s ⊑⇩t t" by (auto simp: less_eq_term_def)
lemma less_eq_termE[elim]:
assumes "s ⊑⇩t t" and "(⋀α :: 'v ⇒ 'a. ⟦s⟧α ⊑ ⟦t⟧α) ⟹ thesis"
shows "thesis" using assms by (auto simp: less_eq_term_def)
sublocale "term": ord "op ⊑⇩t" "op ⊏⇩t".
notation(input) term.greater (infix "⊐⇩t" 50)
notation(input) term.greater_eq (infix "⊒⇩t" 50)
notation term.equiv (infix "≃⇩t" 50)
notation term.equiv_class ("[_]⇩t")
lemma equiv_termI[intro]: "(⋀α :: 'v ⇒ 'a. ⟦s⟧α ≃ ⟦t⟧α) ⟹ s ≃⇩t t" by auto
lemma equiv_termE[elim]:
assumes "s ≃⇩t t" and "(⋀α :: 'v ⇒ 'a. ⟦s⟧α ≃ ⟦t⟧α) ⟹ thesis"
shows "thesis" using assms by auto
lemma less_term_stable[intro]: fixes σ :: "'v ⇒ ('f,'w) term" shows "t ⊏⇩t s ⟹ t⋅σ ⊏⇩t s⋅σ"
by (intro less_termI, auto simp: subst_eval)
lemma less_eq_term_stable[intro]: fixes σ :: "'v ⇒ ('f,'w) term" shows "t ⊑⇩t s ⟹ t⋅σ ⊑⇩t s⋅σ"
by (intro less_eq_termI, auto simp: subst_eval)
end
locale ordered_algebra = ord_algebra + quasi_order
begin
sublocale "term": quasi_order "op ⊑⇩t" "op ⊏⇩t"
apply (unfold_locales, unfold less_term_def less_eq_term_def)
apply (auto dest: order_trans less_trans le_less_trans less_le_trans less_imp_le)
done
end
locale ordered_algebra_hom =
algebra_hom hom I I' + ordered_algebra less_eq less I +
target: ordered_algebra less_eq' less' I'
for hom less_eq less I less_eq' less' I' +
assumes le_hom: "less_eq a b ⟹ less_eq' (hom a) (hom b)"
and less_hom: "less a b ⟹ less' (hom a) (hom b)"
locale ordered_algebra_epim = ordered_algebra_hom + algebra_epim
locale wf_algebra = ordered_algebra where I = I + wf_order
for I :: "'f ⇒ 'a list ⇒ 'a"
begin
interpretation ord_syntax.
sublocale "term": wf_order "op ⊑⇩t :: ('f,'v) term ⇒ ('f,'v) term ⇒ bool" "op ⊏⇩t"
proof
obtain v where "(v :: 'a) = v" by auto
define α where "α ≡ λx :: 'v. v"
fix P s
assume *: "⋀s :: ('f,'v) term. (⋀t. t ⊏⇩t s ⟹ P t) ⟹ P s"
then show "P s"
proof(induct "⟦s⟧α" arbitrary: s rule: less_induct)
case less show ?case
proof (rule less(2))
fix t assume ts: "t ⊏⇩t s"
then have "⟦t⟧α ⊏ ⟦s⟧α" by auto
from less(1)[OF this *] show "P t" by auto
qed
qed
qed
end
locale weak_mono = quasi_order +
fixes f
assumes append_Cons_le_append_Cons:
"⋀a b ls rs. less_eq a b ⟹ less_eq (f (ls @ a # rs)) (f (ls @ b # rs))"
begin
interpretation ord_syntax.
lemma Cons_le_Cons[intro,simp]: "a ⊑ b ⟹ f (a#as) ⊑ f (b#as)"
using append_Cons_le_append_Cons[of _ _ "[]"] by auto
lemma weak_mono_Cons: "weak_mono less_eq less (λas. f (a#as))"
using append_Cons_le_append_Cons[of _ _ "a#_"] by (unfold_locales, auto)
lemma weak_mono_append_left: "weak_mono less_eq less (λas. f (cs@as))"
using append_Cons_le_append_Cons[of _ _ "cs@_"] by (unfold_locales, auto)
lemma weak_mono_append_right: "weak_mono less_eq less (λas. f (as@cs))"
using append_Cons_le_append_Cons by (unfold_locales, auto)
end
lemma (in quasi_order) weak_mono_iff_all_le:
"weak_mono (op ≤) (op <) f ⟷
(∀as bs. length as = length bs ⟶ (∀i < length as. as ! i ≤ bs ! i) ⟶ f as ≤ f bs)"
(is "?l ⟷ ?r")
proof(intro iffI impI allI)
fix as bs
assume "?l" and "length as = length bs" and "∀i < length as. as ! i ≤ bs ! i"
then show "f as ≤ f bs"
proof (induct as arbitrary: bs f)
case (Cons a as bbs)
then obtain b bs
where bbs: "bbs = b#bs"
and ab: "a ≤ b"
and all: "∀i < length as. as ! i ≤ bs ! i"
and len: "length as = length bs"
by (atomize(full), cases bbs, auto)
interpret weak_mono "(op ≤)" "(op <)" f using Cons(2).
have "f (a # as) ≤ f (b # as)" using ab by auto
also have "… ≤ f (b # bs)"
apply (rule Cons(1)) apply fact using all len by auto
finally show ?case unfolding bbs.
qed simp
next
assume r: ?r
show ?l
proof (unfold_locales, intro r[rule_format] allI impI)
fix a b ls rs
assume ab: "a ≤ b"
fix i assume i: "i < length (ls @ a # rs)"
show " (ls @ a # rs) ! i ≤ (ls @ b # rs) ! i"
by(cases i "length ls" rule: linorder_cases, auto simp: ab nth_append)
qed auto
qed
lemmas(in weak_mono) weak_mono_all_le = weak_mono_axioms[unfolded weak_mono_iff_all_le, rule_format]
locale str_mono = weak_mono +
assumes append_Cons_less_append_Cons:
"⋀ls rs a b. less a b ⟹ less (f (ls @ a # rs)) (f (ls @ b # rs))"
begin
interpretation ord_syntax.
lemma Cons_less_Cons[intro,simp]: "a ⊏ b ⟹ f (a#as) ⊏ f (b#as)"
using append_Cons_less_append_Cons[of _ _ "[]"] by auto
lemma str_mono_Cons: "str_mono less_eq less (λas. f (a#as))"
using append_Cons_le_append_Cons[of _ _ "a#_"] append_Cons_less_append_Cons[of _ _ "a#_"]
by (unfold_locales, auto)
lemma str_mono_append_left: "str_mono less_eq less (λas. f (cs@as))"
using append_Cons_le_append_Cons[of _ _ "cs@_"] append_Cons_less_append_Cons[of _ _ "cs@_"]
by (unfold_locales, auto)
lemma str_mono_append_right: "str_mono less_eq less (λas. f (as@cs))"
using append_Cons_le_append_Cons append_Cons_less_append_Cons by (unfold_locales, auto)
end
context weak_mono begin
interpretation ord_syntax.
lemma str_mono_iff_all_le_ex_less:
"str_mono less_eq less f ⟷
(∀as bs. length as = length bs ⟶
(∀i < length as. as ! i ⊑ bs ! i) ⟶
(∃i < length as. as ! i ⊏ bs ! i) ⟶ f as ⊏ f bs)" (is "?l ⟷ ?r")
proof (intro iffI allI impI)
fix as bs
assume ?l and "length as = length bs" and "∀i < length as. as ! i ⊑ bs ! i"
and "∃i < length as. as ! i ⊏ bs ! i"
then show "f as ⊏ f bs"
proof (induct as arbitrary: bs f)
case Nil then show ?case by auto
next
case (Cons a as bbs)
from Cons.prems obtain b bs
where bbs[simp]: "bbs = b#bs"
and len: "length as = length bs"
by (atomize(full), cases bbs, auto)
from Cons.prems
have ab: "a ⊑ b"
and all: "∀i < length as. as ! i ⊑ bs ! i"
and some: "a ⊏ b ∨ (∃i < length as. as ! i ⊏ bs ! i)" by (auto simp: ex_Suc_conv)
interpret str_mono where f = f using Cons.prems(1) .
from some show ?case
proof (elim disjE)
assume ab: "a ⊏ b"
interpret str_mono where f = "λcs. f (a#cs)" by fact
have "f (a#as) ⊑ f (a#bs)" using all len by (simp add: weak_mono_all_le)
also have "… ⊏ f (b#bs)" using ab by auto
finally show ?thesis by simp
next
assume "∃i < length as. as ! i ⊏ bs ! i"
from Cons.hyps[OF _ len all this, of "λcs. f (a#cs)"] str_mono_Cons
have "f (a # as) ⊏ f (a # bs)" by auto
also have "… ⊑ f (b # bs)" using ab by auto
finally show ?thesis by simp
qed
qed
next
assume r: ?r
show ?l
apply unfold_locales apply (intro r[rule_format])
apply simp
apply (metis append_Cons_nth_not_middle eq_imp_le less_imp_le nth_append_length)
by (metis add_Suc_right length_Cons length_append less_add_Suc1 nth_append_length)
qed
end
lemmas(in str_mono) str_mono_all_le_ex_less =
str_mono_axioms[unfolded str_mono_iff_all_le_ex_less, rule_format]
subsection {* Weakly monotone algebra *}
locale weak_mono_algebra = ordered_algebra +
assumes weak_mono: "⋀f. weak_mono less_eq less (I f)"
begin
interpretation ord_syntax.
sublocale weak_mono where f = "I f" by (fact weak_mono)
sublocale "term": weak_mono less_eq_term less_term "Fun f"
by (unfold_locales, intro less_eq_termI, auto intro: append_Cons_le_append_Cons)
lemma ctxt_closed_NS: "ctxt.closed (rel_of op ⊒⇩t)"
by (rule one_imp_ctxt_closed, auto intro: term.append_Cons_le_append_Cons)
lemma subst_closed_S: "subst.closed (rel_of op ⊐⇩t)" by auto
lemma subst_closed_NS: "subst.closed (rel_of op ⊒⇩t)" by auto
lemma le_ctxt_closed[intro]: "s ⊒⇩t t ⟹ C⟨s⟩ ⊒⇩t C⟨t⟩"
using ctxt.closedD[OF ctxt_closed_NS] by auto
lemma eval_le_eval: "∀v ∈ vars_term s. α v ⊑ β v ⟹ ⟦s⟧α ⊑ ⟦s⟧β"
proof (induct s)
case (Var v) then show ?case by auto
next
case IH: (Fun f ss)
{ fix i assume i: "i < length ss"
then have "vars_term (ss!i) ⊆ vars_term (Fun f ss)" by fastforce
with IH(2) have *: "v ∈ vars_term (ss!i) ⟹ α v ⊑ β v" for v by blast
with i have "⟦ss ! i⟧α ⊑ ⟦ss ! i⟧β" by(intro IH(1), auto)
}
then show ?case by(auto intro: weak_mono_all_le)
qed
end
locale wf_weak_mono_algebra = weak_mono_algebra + wf_order
begin
sublocale wf_algebra..
sublocale redpair: redpair_order "rel_of op ⊐⇩t" "rel_of op ⊒⇩t"
using SN ctxt_closed_NS subst_closed_S subst_closed_NS by unfold_locales
end
locale mono_algebra = weak_mono_algebra +
assumes str_mono: "str_mono less_eq less (I f)"
begin
interpretation ord_syntax.
sublocale str_mono where f = "I f" by (fact str_mono)
sublocale "term": str_mono "op ⊑⇩t" "op ⊏⇩t" "(Fun f)"
by (unfold_locales, intro less_termI, auto intro: append_Cons_less_append_Cons)
lemma ctxt_closed_S: "ctxt.closed (rel_of op ⊐⇩t)"
by (rule one_imp_ctxt_closed, auto intro: term.append_Cons_less_append_Cons)
lemma less_ctxt_closed[intro]: "s ⊐⇩t t ⟹ C⟨s⟩ ⊐⇩t C⟨t⟩"
using ctxt.closedD[OF ctxt_closed_S] by auto
lemma upt_append_upt: "i ≤ j ⟹ j ≤ k ⟹ [i..<j] @ [j..<k] = [i..<k]"
using upt_add_eq_append[of i j "k - j"] by auto
lemma eval_less_eval:
assumes "∀v ∈ vars_term s. α v ⊑ β v"
and "∃v ∈ vars_term s. α v ⊏ β v"
shows "⟦s⟧α ⊏ ⟦s⟧β"
proof (insert assms, induct s)
case (Var v)
then show ?case by auto
next
case (Fun f ss)
from Fun.prems
obtain i where i: "i < length ss" and "∃v ∈ vars_term (ss!i). α v ⊏ β v"
by (metis term.sel(4) var_imp_var_of_arg)
with Fun have ex: "⟦ss!i⟧α ⊏ ⟦ss!i⟧β" by auto
have "∀t ∈ set ss. ⟦t⟧α ⊑ ⟦t⟧β" using Fun by (auto intro: eval_le_eval)
with i ex show ?case by (auto intro!: str_mono_all_le_ex_less)
qed
end
locale wf_mono_algebra = mono_algebra + wf_order
begin
sublocale wf_weak_mono_algebra..
end
section {* Models *}
lemma subst_closed_rrstep: "subst.closed r ⟹ rrstep r = r"
apply (intro equalityI subrelI)
apply (force elim: rrstepE)
apply (force intro: rrstepI[of _ _ _ _ Var])
done
subsection {* Non-Monotone Models *}
locale quasi_root_model = ordered_algebra where I = I
for I :: "'f ⇒ 'a list ⇒ 'a" +
fixes R :: "('f,'v) trs"
assumes R_imp_ge: "(l,r) ∈ R ⟹ l ⊒⇩t r"
begin
lemma rrstep_imp_ge: assumes st: "(s,t) ∈ rrstep R" shows "s ⊒⇩t t"
proof-
from st obtain σ l r where s: "s = l⋅σ" and t: "t = r⋅σ" and lr: "(l,r) ∈ R" by (auto simp:rrstep_def')
show ?thesis by (auto simp: s t intro: R_imp_ge lr)
qed
lemma rrstep_subseteq_ge: "rrstep R ⊆ rel_of op ⊒⇩t"
using rrstep_imp_ge by auto
lemma rrsteps_imp_ge: "(s,t) ∈ (rrstep R)⇧* ⟹ s ⊒⇩t t"
by (induct rule: rtrancl_induct, auto dest: rrstep_imp_ge term.order_trans)
lemma rrsteps_subseteq_ge: "(rrstep R)⇧* ⊆ rel_of op ⊒⇩t"
using rrsteps_imp_ge by auto
end
locale wf_quasi_root_model = quasi_root_model + wf_order
begin
sublocale wf_algebra..
lemma SN_rrstep_minus_greater:
assumes "SN (rrstep R - rel_of op ⊐⇩t)" shows "SN(rrstep R)"
proof
fix f
assume 1: "chain (rrstep R) f"
then have "chainp (op ⊒⇩t) f" using rrstep_imp_ge by auto
from term.chainp_ends_nonstrict[OF this]
obtain n where "⋀i. i ≥ n ⟹ ¬ f i ⊐⇩t f (Suc i)" by auto
with 1 have "⋀i. i ≥ n ⟹ (f i, f (Suc i)) ∈ rrstep R - rel_of op ⊐⇩t" by auto
then have "chain (rrstep R - rel_of op ⊐⇩t) (λi. f (n+i))" by auto
from chain_imp_not_SN_on[OF this] assms
show False by fast
qed
end
locale strict_root_model = ordered_algebra where I = I
for I :: "'f ⇒ 'a list ⇒ 'a" +
fixes R :: "('f,'v) trs"
assumes R_imp_greater: "(l,r) ∈ R ⟹ l ⊐⇩t r"
begin
sublocale quasi_root_model using R_imp_greater by (unfold_locales, auto dest: term.less_imp_le)
lemma rrstep_imp_greater: assumes st: "(s,t) ∈ rrstep R" shows "s ⊐⇩t t"
proof-
from st obtain σ l r where s: "s = l⋅σ" and t: "t = r⋅σ" and lr: "(l,r) ∈ R" by (auto simp:rrstep_def')
show ?thesis by (auto simp: s t intro: R_imp_greater lr)
qed
lemma rrstep_subseteq_greater: "rrstep R ⊆ rel_of op ⊐⇩t"
using rrstep_imp_greater by auto
lemma rrsteps_imp_greater: "(s,t) ∈ (rrstep R)⇧+ ⟹ s ⊐⇩t t"
by (induct rule: trancl_induct, auto dest: rrstep_imp_greater term.less_trans)
lemma rrsteps_subseteq_greater: "(rrstep R)⇧+ ⊆ rel_of op ⊐⇩t"
using rrsteps_imp_greater by auto
end
locale wf_root_model = strict_root_model + wf_algebra
begin
sublocale wf_quasi_root_model..
lemma SN_rrstep: "SN (rrstep R)" by (rule SN_rrstep_minus_greater, auto intro: rrstep_imp_greater)
end
lemma rstep_imp_ctxt_rrstep: "(s,t) ∈ rstep R ⟹ ∃(s',t') ∈ rrstep R. ∃C. s = C⟨s'⟩ ∧ t = C⟨t'⟩"
by force
subsection {* Monotone Models for Rewriting *}
locale quasi_model = quasi_root_model + weak_mono_algebra
begin
lemma rstep_imp_ge: assumes st: "(s,t) ∈ rstep R" shows "s ⊒⇩t t"
using rstep_imp_ctxt_rrstep[OF st] rrstep_imp_ge by auto
lemma rstep_subseteq_ge: "rstep R ⊆ rel_of op ⊒⇩t"
using rstep_imp_ge by auto
lemma rsteps_imp_ge: "(s,t) ∈ (rstep R)⇧* ⟹ s ⊒⇩t t"
by (induct rule: rtrancl_induct, auto dest: rstep_imp_ge term.order_trans)
lemma rsteps_subseteq_ge: "(rstep R)⇧* ⊆ rel_of op ⊒⇩t"
using rsteps_imp_ge by auto
end
locale wf_quasi_model = quasi_model + wf_quasi_root_model
begin
lemma SN_minus_greater:
assumes rR: "r ⊆ (rstep R)⇧*"
assumes SN: "SN (r - rel_of op ⊐⇩t)"
shows "SN r"
proof
fix f
assume 1: "chain r f"
have "r ⊆ rel_of op ⊒⇩t" using rR rsteps_imp_ge by auto
with 1 have "chainp (op ⊒⇩t) f" by auto
from term.chainp_ends_nonstrict[OF this]
obtain n where "⋀i. i ≥ n ⟹ ¬ f i ⊐⇩t f (Suc i)" by auto
with 1 have "⋀i. i ≥ n ⟹ (f i, f (Suc i)) ∈ r - rel_of op ⊐⇩t" by auto
then have "chain (r - rel_of op ⊐⇩t) (λi. f (n+i))" by auto
from chain_imp_not_SN_on[OF this] SN_on_subset2[OF _ SN]
show False by auto
qed
text {* Relative rule removal: *}
lemma SN_rstep_minus_greater:
assumes "SN (rstep R - rel_of op ⊐⇩t)" shows "SN (rstep R)"
by (rule SN_minus_greater, insert assms, auto)
text {* Reduction pair processor: *}
lemma SN_relto_rrstep_rstep_minus_greater:
assumes "SN (relto (rrstep R) (rstep R) - rel_of op ⊐⇩t)" shows "SN (relto (rrstep R) (rstep R))"
by (rule SN_minus_greater[OF _ assms], auto dest: rrstep_imp_rstep)
end
locale strict_model = strict_root_model + mono_algebra
begin
sublocale quasi_model using R_imp_greater term.less_imp_le by (unfold_locales, auto)
lemma rstep_imp_greater: assumes st: "(s,t) ∈ rstep R" shows "s ⊐⇩t t"
using rstep_imp_ctxt_rrstep[OF st] rrstep_imp_greater by auto
lemma rsteps_imp_greater: "(s,t) ∈ (rstep R)⇧+ ⟹ s ⊐⇩t t"
by (induct rule: trancl_induct, auto dest:rstep_imp_greater term.less_trans)
end
locale wf_model = strict_model + wf_order
begin
sublocale wf_quasi_model..
sublocale wf_mono_algebra..
text {* A well-founded model proves termination. *}
lemma SN_rstep: "SN (rstep R)"
by (rule SN_rstep_minus_greater, auto intro: rstep_imp_greater)
end
subsection {* Rewrite Algebra *}
text {* A TRS induces a monotone algebra w.r.t. rewriting. *}
locale rewrite_algebra = fixes R :: "('f,'v) trs"
begin
abbreviation less_eq (infix "←⇧*" 50) where "t ←⇧* s ≡ (s,t) ∈ (rstep R)⇧*"
abbreviation less (infix "←⇧+" 50) where "t ←⇧+ s ≡ (s,t) ∈ (rstep R)⇧+"
sublocale ord less_eq less
rewrites "rel_of less_eq = ((rstep R)⇧*)¯"
and "rel_of less = ((rstep R)⇧+)¯"
and "rel_of greater_eq = (rstep R)⇧*"
and "rel_of greater = (rstep R)⇧+"
by auto
notation less_eq (infix "←⇧*" 50)
notation less (infix "←⇧+" 50)
notation greater_eq (infix "→⇧*" 50)
notation greater (infix "→⇧+" 50)
notation equiv (infix "↔⇧*" 50)
sublocale mono_algebra less_eq less Fun
using ctxt_closed_rsteps[of R] ctxt.closed_trancl[OF ctxt_closed_rstep[of R]]
by (unfold_locales, auto simp: dest: ctxt_closed_one)
lemma less_term_is_less[simp]: "less_term = less"
using subst.closed_trancl[OF subst_closed_rstep[of R]]
by (unfold less_term_def, auto intro!: ext elim: allE[of _ Var] simp: term_algebra_eval)
lemma le_term_is_le[simp]: "less_eq_term = less_eq"
using subst.closed_rtrancl[OF subst_closed_rstep[of R]]
by (unfold less_eq_term_def, auto intro!: ext elim: allE[of _ Var] simp: term_algebra_eval)
thm less_term_stable[where 'v='v and 'w='v, simplified]
sublocale strict_model less_eq less Fun by (unfold_locales, auto)
text {*
To any model of @{term R}, there is a homomorphism from the term algebra.
*}
proposition strict_model_imp_hom:
assumes model: "strict_model (less_eq' :: 'b ⇒ _) less' I' R"
shows "∃hom. ordered_algebra_hom hom (op ←⇧*) (op ←⇧+) Fun less_eq' less' I'"
proof-
interpret target: strict_model less_eq' less' I' R using model.
have "ordered_algebra_hom (λs. target.eval s α) (op ←⇧*) (op ←⇧+) Fun less_eq' less' I'" for α
by (unfold_locales, auto dest: target.rsteps_imp_ge target.rsteps_imp_greater)
then show ?thesis by auto
qed
text {*
Further, if there is enough variables, then the model is a homomorphic image of the term algebra.
*}
theorem strict_model_imp_epim:
assumes surj: "surj (α :: 'v ⇒ 'b)"
and model: "strict_model (less_eq' :: 'b ⇒ _) less' I' R"
defines "hom ≡ λs. algebra.eval I' s α"
shows "ordered_algebra_epim hom (op ←⇧*) (op ←⇧+) Fun less_eq' less' I'"
proof-
interpret target: strict_model less_eq' less' I' R using model.
from surj have "surj hom" using target.subset_range_eval[of α] by (auto simp: hom_def)
then show "ordered_algebra_epim hom (op ←⇧*) (op ←⇧+) Fun less_eq' less' I'"
by (unfold_locales, auto dest: target.rsteps_imp_ge target.rsteps_imp_greater simp: hom_def)
qed
end
text {* The next theorem is due to Zantema (JSC 1994): a TRS is terminating if and only if
there is a well-founded model for it.
In paper we don't restrict the domain of interpretations but in Isabelle/HOL we have to.
*}
proposition ex_wf_model_iff_terminating:
fixes R :: "('f,'v) trs"
shows "(∃less_eq less :: ('f,'v) term ⇒ _. ∃ I. wf_model less_eq less I R) ⟷ SN (rstep R)" (is "?l ⟷ ?r")
proof
assume ?l
then obtain less_eq less :: "('f,'v) term ⇒ _" and I where "wf_model less_eq less I R" by auto
then interpret wf_model less_eq less I R by auto
from SN_rstep show ?r.
next
interpret rewrite_algebra R.
assume ?r
then have "SN ((rstep R)⇧+)" by (rule SN_on_trancl)
from SN_induct[OF this]
have "wf_model less_eq less Fun R" by (unfold_locales, auto)
then show ?l by auto
qed
text {* Ordering in the rewrite algebra of R is preserved in any strict model of R. *}
definition models_less
where "models_less (ty :: 'a itself) R t s ⟷
(∀less_eq less :: 'a ⇒ _. ∀ I. strict_model less_eq less I R ⟶ ord_algebra.less_term less I t s)"
lemma(in strict_model) models_lessD:
assumes "models_less (TYPE('a)) R t s" shows "t ⊏⇩t s"
using assms strict_model_axioms by (auto simp: models_less_def)
lemma models_less_imp_rsteps:
assumes "models_less (TYPE(('f,'v) term)) (R::('f,'v) trs) t s"
shows "(s,t) ∈ (rstep R)⇧+"
proof-
interpret rewrite_algebra R.
from models_lessD[OF assms] show ?thesis by auto
qed
lemma rsteps_imp_models_less:
assumes st: "(s,t) ∈ (rstep R)⇧+"
shows "models_less (TYPE('a)) R t s"
proof (unfold models_less_def, intro allI impI)
interpret rewrite_algebra R.
fix less_eq less and I :: "_ ⇒ 'a list ⇒ 'a"
assume "strict_model less_eq less I R"
then interpret target: strict_model less_eq less I R.
from target.rsteps_imp_greater[OF st]
show "target.less_term t s" by auto
qed
subsection {* Models for Equational Theories *}
locale equimodel = weak_mono_algebra where I = I
for I :: "'f ⇒ 'a list ⇒ 'a" +
fixes E :: "('f,'v) trs"
assumes E_imp_equiv: "(l,r) ∈ E ⟹ l ≃⇩t r"
begin
sublocale quasi_model where R = "E⇧↔"
by (unfold_locales, insert E_imp_equiv, auto)
lemma conversion_imp_equiv: assumes "(s,t) ∈ (rstep E)⇧↔⇧*" shows "s ≃⇩t t"
proof-
note * = rsteps_imp_ge[unfolded rstep_simps(5), folded conversion_def]
from *[OF assms[unfolded conversion_inv[of s t]]] *[OF assms]
show ?thesis by auto
qed
end
locale model = algebra I for I :: "'f ⇒ 'a list ⇒ 'a" and E :: "('f,'v) trs" +
assumes E_imp_eq: "(l,r) ∈ E ⟹ ⟦l⟧ = ⟦r⟧"
begin
interpretation ordered: ordered_algebra
where less_eq = "op =" and less = "λx y. False"
by (unfold_locales, auto)
sublocale ordered: equimodel
where less_eq = "op =" and less = "λx y. False"
by (unfold_locales, auto simp: E_imp_eq)
lemma conversion_imp_eq: assumes "(s,t) ∈ (rstep E)⇧↔⇧*" shows "⟦s⟧ = ⟦t⟧"
using ordered.conversion_imp_equiv[OF assms] by auto
end
subsection {* Encoding algebras *}
text {*
Here we ``encode'' an $F$-algebra into a $G$-algebra, where $G$ is supposed to be established
small signature like the semiring signature.
Each function symbol $f \in F$ of arity $n$ is encoded as a term in $T(G,{0..<n})$.
*}
subsubsection {* Syntactic Encodings *}
locale pre_encoding =
fixes E :: "'f ⇒ nat ⇒ ('g, nat) term"
begin
text {* These "pre" locales are needed only for (unconditional) cord equations. *}
abbreviation(input) I where "I f ss ≡ E f (length ss) ⋅ (nth ss)"
sublocale algebra I.
end
locale pre_encoded_algebra = target: algebra I + encoder: pre_encoding E
for I :: "'g ⇒ 'a list ⇒ 'a"
and E :: "'f ⇒ nat ⇒ ('g, nat) term"
begin
abbreviation encode :: "('f,'v) term ⇒ ('g,'v) term" where "encode s ≡ encoder.eval s Var"
abbreviation IE :: "'f ⇒ 'a list ⇒ 'a" where "IE f vs ≡ target.eval (E f (length vs)) (nth vs)"
sublocale algebra IE.
lemma constant_at_via_encoding:
assumes "target.constant_term_on (E f n) i"
shows "constant_at f n i"
proof (intro constant_atI)
fix as :: "'a list" and b
assume 1: "i < n" and 2: "length as = n"
then have [simp]: "op ! (as [i := b]) = (λj. if i = j then b else as ! j)" by auto
from target.constant_term_onD[OF assms, of "λj. as ! j" b, symmetric]
show "target.eval (E f (length (as[i := b]))) (op ! (as[i := b])) =
target.eval (E f (length as)) (op ! as)" by (auto simp: fun_upd_def 2)
qed
definition "constant_positions f n ≡ [i ← [0..<n]. i ∉ vars_term (E f n)]"
lemma constant_positions: "i ∈ set (constant_positions f n) ⟹ constant_at f n i"
apply (rule constant_at_via_encoding)
apply (rule target.constant_term_on_extra_var)
by (auto simp: constant_positions_def)
end
locale pre_encoded_ord_algebra =
ord less_eq less + pre_encoded_algebra I E
for less_eq less :: "'a ⇒ 'a ⇒ bool"
and I :: "'g ⇒ 'a list ⇒ 'a"
and E :: "'f ⇒ nat ⇒ ('g, nat) term"
begin
sublocale target: ord_algebra.
sublocale ord_algebra where I = IE.
end
subsubsection {* Well-Formed Encodings *}
locale encoding = pre_encoding +
assumes var_domain: "i ∈ vars_term (E f n) ⟹ i < n"
locale encoded_algebra = pre_encoded_algebra + encoder: encoding
begin
sublocale algebra_hom "λt. target.eval t α" "encoder.I" IE
apply unfold_locales
by (auto simp: target.eval_hom.hom_eval encoder.var_domain)
lemma eval_via_encoding [simp]: "target.eval (encode s) = ⟦s⟧"
by (intro ext, induct s, auto simp: target.eval_hom.hom_eval encoder.var_domain)
end
locale encoded_ordered_algebra = quasi_order + pre_encoded_ord_algebra + encoded_algebra
begin
sublocale target: ordered_algebra..
sublocale ordered_algebra where I = IE..
end
locale encoded_wf_algebra = wf_order + encoded_ordered_algebra
begin
sublocale target: wf_algebra by (unfold_locales, fact less_induct)
sublocale wf_algebra where I = IE..
end
locale encoded_weak_mono_algebra = encoded_ordered_algebra +
target: weak_mono_algebra
begin
sublocale weak_mono where f = "IE f"
using encoder.var_domain
by (auto simp: weak_mono_iff_all_le intro: target.eval_le_eval)
sublocale weak_mono_algebra where I = IE..
end
locale encoded_mono_algebra = encoded_ordered_algebra +
target: mono_algebra +
assumes mono_vars: "i < n ⟹ i ∈ vars_term (E f n)"
begin
interpretation ord_syntax.
sublocale encoded_weak_mono_algebra ..
sublocale str_mono where f = "IE f"
apply (unfold str_mono_iff_all_le_ex_less)
using encoder.var_domain mono_vars
by (auto intro!: target.eval_less_eval)
sublocale mono_algebra where I = IE..
end
locale encoded_wf_weak_mono_algebra =
encoded_weak_mono_algebra + wf_order
begin
sublocale encoded_wf_algebra..
sublocale wf_weak_mono_algebra where I = IE..
end
locale encoded_wf_mono_algebra =
encoded_mono_algebra + wf_order
begin
sublocale encoded_wf_weak_mono_algebra..
sublocale wf_mono_algebra where I = IE..
end
end