Theory Ground_Critical_Pairs
theory Ground_Critical_Pairs
imports
Generic_Term_Context
Ground_Term_Rewrite_System
Parallel_Rewrite
begin
text‹Adapted from First\_Order\_Rewriting.Critical\_Pairs›
context ground_term_rewrite_system
begin
definition ground_critical_pairs :: "'t rel ⇒ 't rel" where
"ground_critical_pairs R = {(c⟨r⇩2⟩, r⇩1) | c l r⇩1 r⇩2. (c⟨l⟩, r⇩1) ∈ R ∧ (l, r⇩2) ∈ R}"
abbreviation ground_critical_pair_theorem where
"ground_critical_pair_theorem R ≡
WCR (rewrite_in_context R) ⟷ ground_critical_pairs R ⊆ (rewrite_in_context R)⇧↓"
lemma ground_critical_pairs_fork:
fixes R :: "'t rel"
assumes ground_critical_pairs: "(l, r) ∈ ground_critical_pairs R"
shows "(r, l) ∈ (rewrite_in_context R)¯ O rewrite_in_context R"
proof -
obtain c t t' where "l = c⟨t'⟩" and "(c⟨t⟩, r) ∈ R" and "(t, t') ∈ R"
using ground_critical_pairs
unfolding ground_critical_pairs_def
by auto
have "(r, c⟨t⟩) ∈ (rewrite_in_context R)¯"
using ‹(c⟨t⟩, r) ∈ R› subset_rewrite_in_context
by blast
moreover have "(c⟨t⟩, l) ∈ rewrite_in_context R"
using ‹(t, t') ∈ R› ‹l = c⟨t'⟩› rewrite_in_context_def
by fast
ultimately show ?thesis
by auto
qed
lemma ground_critical_pairs_complete:
fixes R :: "'t rel"
assumes
ground_critical_pairs: "(l, r) ∈ ground_critical_pairs R" and
no_join: "(l, r) ∉ (rewrite_in_context R)⇧↓"
shows "¬ WCR (rewrite_in_context R)"
using ground_critical_pairs_fork[OF ground_critical_pairs] no_join
by auto
definition ground_critical_peaks ::"'t rel ⇒ ('t × 't × 't) set" where
"ground_critical_peaks R = { (c⟨r'⟩, c⟨l⟩, r) | l r r' c. (c⟨l⟩, r) ∈ R ∧ (l, r') ∈ R }"
lemma ground_critical_peak_to_pair:
assumes "(l, m, r) ∈ ground_critical_peaks R"
shows "(l, r) ∈ ground_critical_pairs R"
using assms
unfolding ground_critical_peaks_def ground_critical_pairs_def
by blast
end
locale ground_critical_pairs =
term_context_interpretation where More = More and is_var = "λ_. False" +
parallel_rewrite where Fun = Fun
for
More :: "'f ⇒ 'e ⇒ 't list ⇒ 'c ⇒ 't list ⇒ 'c"
begin
lemma ground_critical_peaks_main:
fixes R :: "'t rel" and t u s :: 't
assumes t_u: "(t, u) ∈ rewrite_in_context R" and t_s: "(t, s) ∈ rewrite_in_context R"
shows
"(s, u) ∈ join (rewrite_in_context R) ∨
(∃c l m r. s = c⟨l⟩ ∧ t = c⟨m⟩ ∧ u = c⟨r⟩ ∧
((l, m, r) ∈ ground_critical_peaks R ∨ (r, m, l) ∈ ground_critical_peaks R))"
proof -
let ?R = "rewrite_in_context R"
let ?CP = "ground_critical_peaks R"
from t_u obtain c⇩1 l⇩1 r⇩1 where
l⇩1_r⇩1: "(l⇩1, r⇩1) ∈ R" and
t1: "t = c⇩1⟨l⇩1⟩" and
u: "u = c⇩1⟨r⇩1⟩"
unfolding rewrite_in_context_def
by auto
from t_s obtain c⇩2 l⇩2 r⇩2 where
l⇩2_r⇩2: "(l⇩2, r⇩2) ∈ R" and
t2: "t = c⇩2⟨l⇩2⟩" and
s: "s = c⇩2⟨r⇩2⟩"
unfolding rewrite_in_context_def
by auto
define n where "n = size⇩c c⇩1 + size⇩c c⇩2"
from t1 t2 u s n_def show ?thesis
proof (induct n arbitrary: c⇩1 c⇩2 s t u rule: less_induct)
case (less n c⇩1 c⇩2 s t u)
show ?case
proof (cases "c⇩1 = □")
case Hole: True
show ?thesis
using l⇩1_r⇩1 l⇩2_r⇩2 less.prems
unfolding ground_critical_peaks_def mem_Collect_eq
by (metis Hole apply_hole)
next
case c⇩1_not_hole: False
then obtain f⇩1 e⇩1 ss⇩1 c⇩1' ts⇩1 where c⇩1: "c⇩1 = More f⇩1 e⇩1 ss⇩1 c⇩1' ts⇩1"
using context_destruct
by auto
show ?thesis
proof (cases "c⇩2 = □")
case Hole: True
show ?thesis
using l⇩1_r⇩1 l⇩2_r⇩2 less.prems
unfolding ground_critical_peaks_def mem_Collect_eq
by (metis Hole apply_hole)
next
case c⇩2_not_hole: False
then obtain f⇩2 e⇩2 ss⇩2 c⇩2' ts⇩2 where c⇩2: "c⇩2 = More f⇩2 e⇩2 ss⇩2 c⇩2' ts⇩2"
using context_destruct
by auto
from less(2-3) c⇩1 c⇩2
have id: "(More f⇩1 e⇩1 ss⇩1 c⇩1' ts⇩1)⟨l⇩1⟩ = (More f⇩2 e⇩2 ss⇩2 c⇩2' ts⇩2)⟨l⇩2⟩"
by auto
then have
f: "f⇩1 = f⇩2" and
e: "e⇩1 = e⇩2"
using term_inject
by auto
let ?n⇩1 = "length ss⇩1"
let ?n⇩2 = "length ss⇩2"
show ?thesis
proof (cases "?n⇩1 = ?n⇩2")
case True
with id have
ss: "ss⇩1 = ss⇩2" and
ts: "ts⇩1 = ts⇩2" and
c': "c⇩1'⟨l⇩1⟩ = c⇩2'⟨l⇩2⟩"
using term_inject
by fastforce+
let ?c = "More f⇩2 e⇩2 ss⇩2 □ ts⇩2"
have c⇩1_eq: "c⇩1 = ?c ∘⇩c c⇩1'"
unfolding c⇩1 f e ss ts
by simp
have c⇩2_eq: "c⇩2 = ?c ∘⇩c c⇩2'"
unfolding c⇩2 f ss ts
by simp
define m where
"m = size⇩c c⇩1' + size⇩c c⇩2'"
have m_less_n: "m < n"
unfolding less m_def c⇩1 c⇩2
using subcontext_smaller interpretation_not_hole
by (metis add_less_mono subcontext)
note IH = less(1)[OF m_less_n refl c' refl refl m_def]
then show ?thesis
proof (elim disjE)
assume "(c⇩2'⟨r⇩2⟩, c⇩1'⟨r⇩1⟩) ∈ ?R⇧↓"
then obtain s' where
c⇩1'_s': "(c⇩1'⟨r⇩1⟩, s') ∈ ?R⇧*" and
c⇩2'_s': "(c⇩2'⟨r⇩2⟩, s') ∈ ?R⇧*"
by auto
have "(c⇩1⟨r⇩1⟩, ?c⟨s'⟩) ∈ ?R⇧*"
using c⇩1'_s'
unfolding c⇩1_eq compose_context_iff
by blast
moreover have "(c⇩2⟨r⇩2⟩, ?c⟨s'⟩) ∈ ?R⇧*"
using c⇩2'_s'
unfolding c⇩2_eq compose_context_iff
by blast
ultimately show ?thesis
using less
by auto
next
assume
"∃c l m r.
c⇩2'⟨r⇩2⟩ = c⟨l⟩ ∧
c⇩1'⟨l⇩1⟩ = c⟨m⟩ ∧
c⇩1'⟨r⇩1⟩ = c⟨r⟩ ∧
((l, m, r) ∈ ?CP ∨ (r, m, l) ∈ ?CP)"
then show ?thesis
by (metis c⇩1_eq c⇩2_eq compose_context_iff less.prems(1,3,4))
qed
next
case False
let ?p⇩1 = "?n⇩1 # hole_position c⇩1'"
let ?p⇩2 = "?n⇩2 # hole_position c⇩2'"
let ?one = "c⇩1⟨l⇩1⟩⟦?p⇩1 := r⇩1⟧"
let ?two = "c⇩2⟨l⇩2⟩⟦?p⇩2 := r⇩2⟧"
have parallel_p⇩1_p⇩2: "?p⇩1 ⊥ ?p⇩2"
using False
by auto
have p⇩1: "?p⇩1 ∈ positions c⇩1⟨l⇩1⟩"
unfolding c⇩1
by auto
have p⇩2: "?p⇩2 ∈ positions c⇩1⟨l⇩1⟩"
unfolding c⇩1 id
by auto
have "(?one, ?one⟦?p⇩2 := r⇩2⟧) ∈ rewrite_in_context R"
proof(rule parallel_rewrite_in_context[OF parallel_p⇩1_p⇩2 p⇩1 p⇩2 _ l⇩2_r⇩2])
show "l⇩2 = c⇩1⟨l⇩1⟩ !⇩t ?p⇩2"
unfolding c⇩1 id
by simp
qed
then have "(c⇩1⟨r⇩1⟩, ?one⟦?p⇩2 := r⇩2⟧) ∈ (rewrite_in_context R)⇧*"
unfolding c⇩1
by simp
moreover have "(?two, ?two⟦?p⇩1 := r⇩1⟧) ∈ rewrite_in_context R"
proof (rule parallel_rewrite_in_context[OF parallel_pos_sym[OF parallel_p⇩1_p⇩2]])
show "?p⇩1 ∈ positions c⇩2⟨l⇩2⟩"
unfolding c⇩2 id[symmetric]
by auto
next
show "?p⇩2 ∈ positions c⇩2⟨l⇩2⟩"
unfolding c⇩2
by auto
next
show "l⇩1 = c⇩2⟨l⇩2⟩ !⇩t ?p⇩1"
unfolding c⇩2 id[symmetric]
by simp
next
show "(l⇩1, r⇩1) ∈ R"
using l⇩1_r⇩1 .
qed
then have "(c⇩2⟨r⇩2⟩, ?two⟦?p⇩1 := r⇩1⟧) ∈ (rewrite_in_context R)⇧*"
unfolding c⇩2
by simp
moreover have "?one⟦?p⇩2 := r⇩2⟧ = (c⇩1⟨l⇩1⟩⟦?p⇩2 := r⇩2⟧⟦?p⇩1 := r⇩1⟧)"
by (rule parallel_replace_at[OF parallel_p⇩1_p⇩2 p⇩1 p⇩2])
then have "?one⟦?p⇩2 := r⇩2⟧ = ?two⟦?p⇩1 := r⇩1⟧"
unfolding c⇩1 c⇩2 id .
ultimately show ?thesis
unfolding less
by (intro disjI1) auto
qed
qed
qed
qed
qed
lemma ground_critical_pairs_main:
assumes "(s, t⇩1) ∈ rewrite_in_context R" "(s, t⇩2) ∈ rewrite_in_context R"
shows
"(t⇩1, t⇩2) ∈ (rewrite_in_context R)⇧↓ ∨
(∃c l r. t⇩1 = c⟨l⟩ ∧ t⇩2 = c⟨r⟩ ∧
((l, r) ∈ ground_critical_pairs R ∨ (r, l) ∈ ground_critical_pairs R))"
using assms ground_critical_peaks_main ground_critical_peak_to_pair
by metis
lemma ground_critical_pairs:
assumes ground_critical_pairs:
"⋀l r. (l, r) ∈ ground_critical_pairs R ⟹ l ≠ r ⟹
∃s. (l, s) ∈ (rewrite_in_context R)⇧* ∧ (r, s) ∈ (rewrite_in_context R)⇧*"
shows "WCR (rewrite_in_context R)"
proof (intro WCR_onI)
let ?R = "rewrite_in_context R"
let ?CP = "ground_critical_pairs R"
fix s t⇩1 t⇩2
assume steps: "(s, t⇩1) ∈ ?R" "(s, t⇩2) ∈ ?R"
let ?p = "λs'. (t⇩1, s') ∈ ?R⇧* ∧ (t⇩2, s') ∈ ?R⇧*"
from ground_critical_pairs_main [OF steps]
have "∃s'. ?p s'"
using ground_critical_pairs rewrite_in_context_trancl_add_context
by (metis joinE rtrancl.rtrancl_refl)
then show "(t⇩1, t⇩2) ∈ ?R⇧↓"
by auto
qed
theorem ground_critical_pair_theorem: "ground_critical_pair_theorem R" (is "?l = ?r")
proof (rule iffI)
assume ?l
with ground_critical_pairs_complete show ?r
by auto
next
assume ?r
with ground_critical_pairs show ?l
by auto
qed
end
end