theory RPO_Memoized
imports
RPO
RPO_Impl
"../Auxiliaries/Multiset_Extension_Impl"
TA.SubList
"../Auxiliaries/Memories"
begin
type_synonym ('m, 'a) memo = "'m ⇒ ('a × 'm)"
type_synonym 'f prec_fct = "('f × nat ⇒ 'f × nat ⇒ bool × bool) × ('f × nat ⇒ bool)"
type_synonym 'f status_fct = "'f × nat ⇒ order_tag"
fun any_nstri_efficient_m :: "('a ⇒ ('m, bool × bool) memo) ⇒ 'a list ⇒ ('m, bool) memo"
where
"any_nstri_efficient_m f [] m = (False, m)" |
"any_nstri_efficient_m f (a # as) m = (let ((_, ns), m') = f a m in
if ns then (True, m') else any_nstri_efficient_m f as m')"
fun all_stri_efficient_m :: "('a ⇒ ('m, bool × bool) memo) ⇒ 'a list ⇒ ('m, bool) memo"
where
"all_stri_efficient_m f [] m = (True, m)" |
"all_stri_efficient_m f (a # as) m = (let ((s, _), m') = f a m in
if s then all_stri_efficient_m f as m' else (False, m'))"
lemma any_nstri_efficient_m[fundef_cong]:
assumes "⋀ s m. s ∈ set ss ⟹ f s m = g s m"
shows "any_nstri_efficient_m f ss m = any_nstri_efficient_m g ss m"
using assms proof (induct ss arbitrary: m)
case (Cons s ss)
show ?case
proof (cases "f s m")
case (Pair res m')
with Cons have rec: "any_nstri_efficient_m f ss m' = any_nstri_efficient_m g ss m'" by auto
from Pair rec show ?thesis
by (simp add: Cons(2)[of s m, simplified], cases res, auto)
qed
qed simp
lemma all_stri_efficient_m [fundef_cong] :
assumes "⋀ t m. t ∈ set ts ⟹ f t m = g t m"
shows "all_stri_efficient_m f ts m = all_stri_efficient_m g ts m"
using assms proof (induct ts arbitrary: m)
case (Cons t ts)
show ?case
proof (cases "f t m")
case (Pair res m')
with Cons have rec: "all_stri_efficient_m f ts m' = all_stri_efficient_m g ts m'" by auto
from Pair rec show ?thesis
by (simp add: Cons(2)[of t m, simplified], cases res, auto)
qed
qed simp
fun filter_not_stri_efficient_m_aux :: "('a ⇒ ('m, bool × bool) memo) ⇒ 'a list ⇒ 'a list ⇒ ('m, 'a list) memo"
where
"filter_not_stri_efficient_m_aux f [] bs m = (bs, m)" |
"filter_not_stri_efficient_m_aux f (a # as) bs m = (
let ((s, _), m') = f a m in
if s
then filter_not_stri_efficient_m_aux f as bs m'
else filter_not_stri_efficient_m_aux f as (a # bs) m')"
definition filter_not_stri_efficient_m:: "('a ⇒ ('m, bool × bool) memo) ⇒ 'a list ⇒ ('m, 'a list) memo"
where
"filter_not_stri_efficient_m f as m ≡ let (ys, m') = filter_not_stri_efficient_m_aux f as [] m in (rev ys, m')"
lemma filter_not_stri_efficient_m_aux[fundef_cong]:
assumes "⋀ a b m. a ∈ set as ⟹ f a m = g a m"
shows "filter_not_stri_efficient_m_aux f as bs m =
filter_not_stri_efficient_m_aux g as bs m"
using assms proof (induct as arbitrary: bs m)
case (Cons a as bs m)
show ?case
proof (cases "f a m")
case (Pair sns m')
obtain s ns where Psns: "sns = (s, ns)" by (cases sns) auto
from Pair and Psns and Cons(2) have "g a m = ((s, ns), m')" by simp
with Psns and Pair and Cons show ?thesis by simp
qed
qed auto
lemma filter_not_stri_efficient_m[fundef_cong]:
assumes "⋀ a b m. a ∈ set as ⟹ f a m = g a m"
shows "filter_not_stri_efficient_m f as m =
filter_not_stri_efficient_m g as m"
unfolding filter_not_stri_efficient_m_def
using assms and filter_not_stri_efficient_m_aux
by force
lemma filter_not_stri_efficient_m_aux_subseq:
"subseq (rev (fst (filter_not_stri_efficient_m_aux f as bs m))) ((rev bs) @ as)"
proof (induct as arbitrary: bs m)
case (Cons a as)
obtain sns m' where P1: "f a m = (sns, m')" by (cases "f a m") auto
obtain s ns where P2: "sns = (s, ns)" by (cases sns) auto
show ?case
proof (cases s)
case True
with Cons [of "bs" m'] P1 P2
have e1: "subseq (rev (fst (filter_not_stri_efficient_m_aux f (a # as) bs m))) ((rev bs) @ as)"
by simp
note subseq_refl = subseq_order.order.refl
from e1 list_emb_append_mono [OF subseq_refl [of "rev bs"] list_emb_Cons [OF subseq_refl [of as], of a]]
and subseq_trans show ?thesis by simp
next
case False with Cons [of "a # bs" m'] P1 P2 show ?thesis by simp
qed
qed auto
lemma filter_not_stri_efficient_m_subseq:
"subseq (fst (filter_not_stri_efficient_m f as m)) as"
proof -
obtain ys m' where Hrew: "filter_not_stri_efficient_m_aux f as [] m = (ys, m')"
by (cases "filter_not_stri_efficient_m_aux f as [] m") auto
with filter_not_stri_efficient_m_aux_subseq[of f as "[]" m]
have "subseq (rev ys) as" by simp
thus ?thesis using Hrew unfolding filter_not_stri_efficient_m_def by simp
qed
lemma filter_not_stri_efficient_m_submultiset:
"mset (fst (filter_not_stri_efficient_m f as m)) ⊆# mset as"
using subseq_submultiset filter_not_stri_efficient_m_subseq by force
lemma filter_not_stri_efficient_m_subset:
"set (fst (filter_not_stri_efficient_m f as m)) ≤ set as"
using subseq_subset filter_not_stri_efficient_m_subseq by force
lemma length_filter_not_stri_efficient_m[simp]:
"length (fst (filter_not_stri_efficient_m f as m)) ≤ length as"
using list_emb_length filter_not_stri_efficient_m_subseq by force
fun diag_l :: "('a × 'b) ⇒ (('a × 'a) × 'b)" where
"diag_l (a, b) = ((a, a), b)"
fun lex_ext_efficient_m :: "('a ⇒ 'a ⇒ ('m, bool × bool) memo) ⇒ 'a list ⇒ 'a list ⇒ ('m, bool × bool) memo"
where
"lex_ext_efficient_m f [] [] m = ((False, True), m)" |
"lex_ext_efficient_m f (_#_) [] m = ((True, True), m)" |
"lex_ext_efficient_m f [] (_#_) m = ((False, False), m)" |
"lex_ext_efficient_m f (a#as) (b#bs) m = (let ((s,ns),m') = f a b m in
if s then ((True, True), m')
else if ns then (lex_ext_efficient_m f as bs m')
else ((False, False), m'))"
lemma lex_ext_efficient_m_cong[fundef_cong] : fixes f g ss ts m
assumes "⋀ s t m. ⟦s ∈ set ss; t ∈ set ts⟧ ⟹ f s t m = g s t m"
shows "lex_ext_efficient_m f ss ts m = lex_ext_efficient_m g ss ts m"
using assms
proof (induct ss arbitrary: ts m)
case Nil
thus ?case by (cases ts, auto)
next
case (Cons s ss) note oCons = this
show ?case
proof (cases ts)
case (Cons t ts')
with oCons have id: "g s t m = f s t m" by simp
show ?thesis
proof (cases "f s t m")
case (Pair res m')
from oCons Cons have id2: "lex_ext_efficient_m f ss ts' m' = lex_ext_efficient_m g ss ts' m'" by auto
show ?thesis
by (simp add: Pair Cons id, cases res, auto simp: id2)
qed
qed auto
qed
fun mul_ext_efficient_m :: "('a ⇒ 'a ⇒ ('m, bool × bool) memo) ⇒ 'a list ⇒ 'a list ⇒ ('m, bool × bool) memo"
and mul_ex_dom_efficient_m :: "('a ⇒ 'a ⇒ ('m, bool × bool) memo) ⇒ 'a list ⇒ 'a list ⇒ 'a ⇒ 'a list ⇒ ('m, bool × bool) memo"
where
"mul_ext_efficient_m f [] [] m = ((False, True), m)"
| "mul_ext_efficient_m f [] _ m = ((False, False),m)"
| "mul_ext_efficient_m f _ [] m = ((True, True), m)"
| "mul_ext_efficient_m f xs (y # ys) m = mul_ex_dom_efficient_m f xs [] y ys m"
| "mul_ex_dom_efficient_m f [] xs' y ys m = ((False, False), m)"
| "mul_ex_dom_efficient_m f (x # xs) xs' y ys m =
(let ((s, ns), m') = f x y m in
if s then
let (ys', m2) = filter_not_stri_efficient_m (f x) ys m' in
let ((s', ns'), m3) = mul_ext_efficient_m f (xs @ xs') ys' m2 in
if ns' then ((True, True), m3) else mul_ex_dom_efficient_m f xs (x # xs') y ys m3
else if ns then
let ((s2, ns2), m4) = mul_ext_efficient_m f (xs @ xs') ys m' in
if s2 then ((True, True), m4) else
let ((s3, ns3), m5) = mul_ex_dom_efficient_m f xs (x # xs') y ys m4 in
if s3 then ((True, True), m5) else ((False, ns2 ∨ ns3), m5)
else mul_ex_dom_efficient_m f xs (x # xs') y ys m')"
lemma mul_ext_efficient_m_cong[fundef_cong]:
assumes "⋀x y m. x ∈ set xs ⟹ y ∈ set ys ⟹ f x y m = g x y m"
shows "mul_ext_efficient_m f xs ys m = mul_ext_efficient_m g xs ys m"
proof -
note * = mul_ext_efficient_m.simps[simp del] mul_ex_dom_efficient_m.simps[simp del] and
p = prod.collapse and r = refl
have "(⋀x' y' m. x' ∈ set xs ⟹ y' ∈ set ys ⟹ f x' y' m = g x' y' m) ⟹
mul_ext_efficient_m f xs ys m = mul_ext_efficient_m g xs ys m"
"(⋀x' y' m. x' ∈ set (xs @ xs') ⟹ y' ∈ set (y # ys) ⟹ f x' y' m = g x' y' m) ⟹
mul_ex_dom_efficient_m f xs xs' y ys m = mul_ex_dom_efficient_m g xs xs' y ys m" for xs' y
proof (induct f xs ys m and f xs xs' y ys m rule: mul_ext_efficient_m_mul_ex_dom_efficient_m.induct)
case (6 f x xs xs' y ys m)
have [simp]: "f x y m = g x y m" (is "_ = ?g") using 6(6) by auto
obtain s ns m' where [simp]: "g x y m = ((s, ns), m')" by (metis prod.collapse)
have [simp]: "filter_not_stri_efficient_m (f x) ys m' = filter_not_stri_efficient_m (g x) ys m'"
using 6(6) by (auto intro: filter_not_stri_efficient_m)
obtain ys' m2 where [simp]: "filter_not_stri_efficient_m (g x) ys m' = (ys', m2)" by (metis prod.collapse)
have [simp]: "s ⟹ mul_ext_efficient_m f (xs @ xs') ys' m2 = mul_ext_efficient_m g (xs @ xs') ys' m2"
using 6(6) filter_not_stri_efficient_m_subset[of "g x" ys m']
by (auto intro!: 6(1)[OF r p p _ r, of _ _ m'])
obtain s' ns' m3 where [simp]: "mul_ext_efficient_m g (xs @ xs') ys' m2 = ((s', ns'), m3)" by (metis prod.collapse)
have [simp]: "¬ s ⟹ ns ⟹ mul_ext_efficient_m f (xs @ xs') ys m' = mul_ext_efficient_m g (xs @ xs') ys m'"
using 6(6) by (auto intro: 6(3)[OF r p p])
obtain s2 ns2 m4 where [simp]: "mul_ext_efficient_m g (xs @ xs') ys m' = ((s2, ns2), m4)" by (metis prod.collapse)
have [simp]: "¬ s ⟹ ns ⟹ ¬ s2 ⟹ mul_ex_dom_efficient_m f xs (x # xs') y ys m4 = mul_ex_dom_efficient_m g xs (x # xs') y ys m4"
using 6(6) by (auto intro: 6(4)[OF r p p _ _ r p p, of m', simplified])
show ?case unfolding mul_ex_dom_efficient_m.simps using 6(6)
by (auto intro: 6(2)[OF r p p _ r p r p p, of m', simplified]
6(5)[OF r p p, simplified])
qed (auto simp: *)
then show ?thesis using assms by auto
qed
fun rpo_efficient_m ::
"('m, ('f,'v) term × ('f, 'v) term, bool × bool) memory ⇒ 'f prec_fct ⇒ 'f status_fct ⇒
('f,'v) term ⇒ ('f,'v) term ⇒ ('m, bool × bool) memo" where
"rpo_efficient_m model pr tag s t m = (case (memory.lookup model m (s,t)) of
Some v ⇒ (v, m)
| None ⇒ let (res, res_m) =
(case (s,t) of
(Var x, Var y) ⇒ ((False, x = y), m)
| (Var x, Fun g ts) ⇒ ((False, ts = [] ∧ (snd pr) (g,0)), m)
| (Fun f ss, Var y) ⇒ diag_l (any_nstri_efficient_m (λs. rpo_efficient_m model pr tag s (Var y)) ss m)
| (Fun f ss, Fun g ts) ⇒
(let (any, m') = any_nstri_efficient_m (λs. rpo_efficient_m model pr tag s (Fun g ts)) ss m in
if any then ((True, True), m')
else let m = length ss in let n = length ts in
let (prs, prns) = fst pr (f,m) (g,n) in
if prns
then let (all, m'') = all_stri_efficient_m (rpo_efficient_m model pr tag (Fun f ss)) ts m' in
if all
then if prs
then ((True, True), m'')
else let cf = tag (f,m) in
if cf = tag (g,n)
then if cf = Mul
then mul_ext_efficient_m (rpo_efficient_m model pr tag) ss ts m''
else lex_ext_efficient_m (rpo_efficient_m model pr tag) ss ts m''
else let b = (n = 0) in ((m ≠ 0 ∧ b, b), m'')
else ((False, False), m'')
else ((False, False), m')
)) in (res, memory.store model res_m ((s, t), res)))"
locale memoized_rpo =
fixes model :: "('m, ('f,'v) term × ('f, 'v) term, bool × bool)memory"
fixes model_P :: "('m, ('f, 'v)term × ('f, 'v)term, bool × bool)memory ⇒ 'm
⇒ ((('f, 'v)term × ('f, 'v)term) ⇒ bool × bool) ⇒ bool"
assumes model_satisfactory: "satisfactory model_P model"
begin
abbreviation rpo_efficient where "rpo_efficient ≡ rpo_efficient_m model"
definition m_rpo_valid where
"m_rpo_valid pr tag m = model_P model m (λp. rpo_unbounded_impl pr tag (fst p) (snd p))"
lemma lookup_valid:
assumes "model_P model m f"
shows "valid model m f"
using model_satisfactory assms by simp
lemma store_valid:
assumes "model_P model M f"
shows "model_P model (memory.store model M (a, f a)) f"
using model_satisfactory assms by (cases a) auto
lemma any_nstri_efficient_m_sound:
assumes "⋀s m. s ∈ set ss ∧ m_valid f m ⟹ fst (fE s m) = f s t ∧ m_valid f (snd (fE s m))"
and "m_valid f m"
shows "m_valid f (snd (any_nstri_efficient_m fE ss m))
∧ fst (any_nstri_efficient_m fE ss m) = (∃ s ∈ set ss. snd (f s t))"
using assms proof (induct ss arbitrary: m)
case Nil
have "any_nstri_efficient_m fE [] m = (False,m)" by simp
moreover have "(∃ s ∈ set []. snd (f s t)) = False" by simp
ultimately show ?case using Nil(2) by simp
next
case (Cons u us)
obtain v m' where fE_val: "fE u m = (v, m')" by (cases "fE u m") auto
hence m':"snd (fE u m) = m'" by simp
from Cons have u_vals_sound:"fst (fE u m) = f u t ∧ m_valid f (snd (fE u m))" by simp
with m' have m'_valid:"m_valid f m'" by (simp add: assms)
obtain s ns where v_def: "v = (s, ns)" by (cases v) auto
with u_vals_sound fE_val have f_val:"f u t = (s, ns)" by simp
show ?case
proof (cases ns)
case True
with v_def fE_val have "snd (any_nstri_efficient_m fE (u # us) m) = m'" by simp
with m'_valid have valid_memory: "m_valid f (snd (any_nstri_efficient_m fE (u # us) m))" by simp
from True v_def fE_val have any_nstri_efficient_m_val:
"fst (any_nstri_efficient_m fE (u # us) m) = True" by simp
from True f_val have ex_val:"(∃ s ∈ set (u # us). snd (f s t)) = True" by simp
with any_nstri_efficient_m_val valid_memory show ?thesis by simp
next
case False
with v_def fE_val have any_nstri_efficient_m_val:
"any_nstri_efficient_m fE (u # us) m = any_nstri_efficient_m fE us m'" by simp
from Cons(2) have "⋀s m. s ∈ set us ∧ m_valid f m ⟹ fst (fE s m) = f s t
∧ m_valid f (snd (fE s m))" by simp
with Cons(1)[of m'] m'_valid have rec:"m_valid f (snd (any_nstri_efficient_m fE us m'))
∧ fst (any_nstri_efficient_m fE us m') = (∃ s ∈ set us. snd (f s t))" by simp
from f_val False have ex_val:"(∃ s ∈ set (u # us). snd (f s t)) = (∃s ∈ set us. snd (f s t))"
by simp
with rec any_nstri_efficient_m_val show ?thesis by simp
qed
qed
lemma all_stri_efficient_m_sound:
assumes "⋀t m. t ∈ set ts ∧ m_valid f m ⟹ fst (fE t m) = f s t ∧ m_valid f (snd (fE t m))"
and "m_valid f m"
shows "m_valid f (snd (all_stri_efficient_m fE ts m))
∧ fst (all_stri_efficient_m fE ts m) = (∀ t ∈ set ts. fst (f s t))"
using assms proof (induct ts arbitrary: m)
case Nil
have "all_stri_efficient_m fE [] m = (True, m)" by simp
moreover have "(∀ t ∈ set []. fst (f s t)) = True" by simp
ultimately show ?case using Nil(2) by simp
next
case (Cons u us)
obtain v m' where fE_val: "fE u m = (v, m')" by (cases "fE u m") auto
hence m':"snd (fE u m) = m'" by simp
from Cons have u_vals_sound:"fst (fE u m) = f s u ∧ m_valid f (snd (fE u m))" by simp
with m' have m'_valid: "m_valid f m'" by (simp add: assms)
obtain stri nstri where v_def: "v = (stri, nstri)" by (cases v) auto
with u_vals_sound fE_val have f_val:"f s u = (stri, nstri)" by simp
show ?case
proof (cases stri)
case False
with v_def fE_val have "snd (all_stri_efficient_m fE (u # us) m) = m'" by simp
with m'_valid have valid_memory:"m_valid f (snd (all_stri_efficient_m fE (u # us) m))" by simp
from False v_def fE_val have all_stri_efficient_m_val:
"fst (all_stri_efficient_m fE (u # us) m) = False" by simp
with False f_val valid_memory show ?thesis by simp
next
case True
with v_def fE_val have all_stri_efficient_m_val:
"all_stri_efficient_m fE (u # us) m = all_stri_efficient_m fE us m'" by simp
from Cons(2) have "⋀t m. t ∈ set us ∧ m_valid f m ⟹ fst (fE t m) = f s t
∧ m_valid f (snd (fE t m))" by simp
with Cons(1)[of m'] m'_valid have rec:"m_valid f (snd (all_stri_efficient_m fE us m'))
∧ fst (all_stri_efficient_m fE us m') = (∀ t ∈ set us. fst (f s t))" by simp
from f_val True have all_val:"(∀ t ∈ set (u # us). fst (f s t)) = (∀ t ∈ set us. fst (f s t))"
by simp
with rec all_stri_efficient_m_val show ?thesis by simp
qed
qed
lemma filter_not_stri_efficient_m_aux_sound:
assumes "⋀t m. t ∈ set ts ∧ model_P model m f ⟹ fst (fE t m) = f (s, t) ∧ model_P model (snd (fE t m)) f"
and "model_P model m f"
and "∀ t ∈ set res. ¬ fst (f (s, t))"
shows "model_P model (snd (filter_not_stri_efficient_m_aux fE ts res m)) f
∧ rev (fst (filter_not_stri_efficient_m_aux fE ts res m)) = [t← ((rev res) @ ts) . ¬ fst (f (s, t))]"
using assms proof (induct ts arbitrary: m res)
case Nil show ?case
proof (rule conjI)
from Nil(2) show "model_P model (snd (filter_not_stri_efficient_m_aux fE [] res m)) f" by simp
from Nil(3) show "rev (fst (filter_not_stri_efficient_m_aux fE [] res m))
= [t← (rev res @ []) . ¬ fst (f (s, t))]" by (induct res, simp_all)
qed
next
case (Cons u us)
obtain v m' where fE_val: "fE u m = (v, m')" by (cases "fE u m") auto
hence m':"snd (fE u m) = m'" by simp
from Cons have u_vals_sound:"fst (fE u m) = f (s, u) ∧ model_P model (snd (fE u m)) f" by simp
with m' have m'_valid: "model_P model m' f" by (simp add: assms)
obtain stri nstri where v_def: "v = (stri, nstri)" by (cases v) auto
with u_vals_sound fE_val have f_val:"f (s, u) = (stri, nstri)" by simp
show ?case
proof (cases stri)
case True
with v_def fE_val
have all_stri_efficient_m_val: "filter_not_stri_efficient_m_aux fE (u # us) res m
= filter_not_stri_efficient_m_aux fE us res m'" by simp
from f_val True have nfsu: "(¬ fst (f (s, u))) = False" by simp
from Cons(2) have "⋀t m. t ∈ set us ∧ model_P model m f ⟹ fst (fE t m) = f (s, t)
∧ model_P model (snd (fE t m)) f" by simp
with Cons(1)[of m' res] Cons(4) m'_valid all_stri_efficient_m_val nfsu
show ?thesis by simp
next
case False
with v_def fE_val
have all_stri_efficient_m_val: "filter_not_stri_efficient_m_aux fE (u # us) res m
= filter_not_stri_efficient_m_aux fE us (u # res) m'" by simp
from Cons(4) False f_val have acc_sound: "∀t ∈ set (u # res). ¬ fst (f (s, t))" by simp
from Cons(2) have "⋀t m. t ∈ set us ∧ model_P model m f ⟹ fst (fE t m) = f (s, t)
∧ model_P model (snd (fE t m)) f" by simp
with Cons(1)[of m' "u # res"] acc_sound m'_valid all_stri_efficient_m_val
show ?thesis by simp
qed
qed
lemma filter_not_stri_efficient_m_sound:
assumes "⋀t m. t ∈ set ts ∧ model_P model m f ⟹ fst (fE t m) = f (s, t) ∧ model_P model (snd (fE t m)) f"
and "model_P model m f"
shows "model_P model (snd (filter_not_stri_efficient_m fE ts m)) f
∧ fst (filter_not_stri_efficient_m fE ts m) = [y←ts . ¬ fst (f (s, y))]"
proof -
obtain ys m' where Hrew: "filter_not_stri_efficient_m_aux fE ts [] m = (ys, m')"
by (cases "filter_not_stri_efficient_m_aux fE ts [] m") auto
from filter_not_stri_efficient_m_aux_sound[OF assms(1) assms(2), of ts "λ_ m. m" "[]"] assms Hrew
show ?thesis unfolding filter_not_stri_efficient_m_def by simp
qed
declare lex_ext_unbounded.simps[simp]
lemma lex_ext_efficient_m_sound:
assumes "⋀t s m. s ∈ set ss ∧ t ∈ set ts ∧ model_P model m f ⟹ fst (fE s t m) = f (s, t)
∧ model_P model (snd (fE s t m)) f"
and "model_P model m f"
shows "model_P model (snd (lex_ext_efficient_m fE ss ts m)) f
∧ fst (lex_ext_efficient_m fE ss ts m) = lex_ext_unbounded (λs t. f (s, t)) ss ts"
using assms proof (induct ss ts arbitrary: m rule: List.list_induct2')
case (1 m)
have "lex_ext_efficient_m fE [] [] m = ((False,True),m)" by simp
moreover have "lex_ext_unbounded (λ s t. f (s, t)) [] [] = (False, True)" by simp
ultimately show ?case using 1(2) by simp
next
case (2 a as m)
have "lex_ext_efficient_m fE (a # as) [] m = ((True,True),m)" by simp
moreover have "lex_ext_unbounded (λs t. f (s, t)) (a # as) [] = (True, True)" by simp
ultimately show ?case using 2(2) by simp
next
case (3 b bs m)
have "lex_ext_efficient_m fE [] (b # bs) m = ((False,False),m)" by simp
moreover have "lex_ext_unbounded (λs t. f (s, t)) [] (b # bs) = (False, False)" by simp
ultimately show ?case using 3(2) by simp
next
case (4 a as b bs m)
obtain v m' where fE_val: "fE a b m = (v, m')" by (cases "fE a b m") auto
from 4(2)[of a b m] 4(3) have fE_sound: "fst (fE a b m) = f (a, b) ∧ model_P model (snd (fE a b m)) f"
by simp
with fE_val have m'_valid: "model_P model m' f" by simp
obtain s ns where v_def: "v = (s, ns)" by (cases v) auto
with fE_sound fE_val have f_val:"f (a, b) = (s,ns)" by simp
show ?case
proof (cases s)
case True
with fE_val v_def have lex_ext_efficient_m_val:
"lex_ext_efficient_m fE (a # as) (b # bs) m = ((True,True),m')" by simp
from f_val True
have lex_ext_unbounded_val:"lex_ext_unbounded (λs t. f (s, t)) (a # as) (b # bs) = (True,True)"
by simp
with m'_valid lex_ext_efficient_m_val show ?thesis by simp
next
case False note sFalse = this
show ?thesis
proof (cases ns)
case True
from 4(2) have "⋀s t m. s ∈ set as ∧ t ∈ set bs ∧ model_P model m f ⟹ fst (fE s t m) = f (s, t)
∧ model_P model (snd (fE s t m)) f" by simp
from this 4(1)[of m'] m'_valid have rec: "model_P model (snd (lex_ext_efficient_m fE as bs m')) f
∧ fst (lex_ext_efficient_m fE as bs m') = lex_ext_unbounded (λs t. f (s, t)) as bs"
by simp
from sFalse True v_def fE_val
have lex_ext_efficient_m_val: "lex_ext_efficient_m fE (a # as) (b # bs) m
= lex_ext_efficient_m fE as bs m'" by simp
from sFalse True f_val
have lex_ext_unbounded_val:"lex_ext_unbounded (λs t. f (s, t)) (a # as) (b # bs)
= lex_ext_unbounded (λs t. f (s, t)) as bs" by simp
with lex_ext_efficient_m_val rec show ?thesis by simp
next
case False
with sFalse v_def fE_val have lex_ext_efficient_m_val:
"lex_ext_efficient_m fE (a # as) (b # bs) m = ((False,False),m')" by simp
from sFalse False f_val
have lex_ext_unbounded_val: "lex_ext_unbounded (λs t. f (s, t)) (a # as) (b # bs) = (False,False)"
by simp
with lex_ext_efficient_m_val m'_valid show ?thesis by simp
qed
qed
qed
declare lex_ext_unbounded.simps[simp del]
lemma mul_ext_impl_s_imp_ns:
"fst (mul_ext_impl f xs ys) ⟹ snd (mul_ext_impl f xs ys)"
by (auto simp: mul_ext_impl_sound0 mult2_impl_sound mult2_alt_ns_conv)
lemma mul_ex_dom_s_imp_ns:
"fst (mul_ex_dom f xs xs' y ys) ⟹ snd (mul_ex_dom f xs xs' y ys)"
by (auto simp:mul_ext_impl_sound0 mult2_impl_sound mult2_alt_ns_conv)
lemma mul_ext_efficient_m_sound:
assumes "⋀t s m. s ∈ set ps ∧ t ∈ set qs ∧ model_P model m f ⟹ fst (fE s t m) = f (s, t)
∧ model_P model (snd (fE s t m)) f"
and "model_P model m f"
shows
"model_P model (snd (mul_ext_efficient_m fE ps qs m)) f
∧ fst (mul_ext_efficient_m fE ps qs m) = mul_ext_impl (λs t. f (s, t)) ps qs"
proof -
note * = mul_ext_efficient_m.simps[simp del] mul_ex_dom_efficient_m.simps[simp del]
mul_ext_impl.simps[simp del] mul_ex_dom.simps[simp del] and filter.simps[simp del]
and p = prod.collapse and r = refl
have
"(⋀m. model_P model m f ⟹
(⋀x y. x ∈ set xs ⟹ y ∈ set ys ⟹
fst (fE x y m) = f (x, y) ∧ model_P model (snd (fE x y m)) f)) ⟹
model_P model m f ⟹ model_P model (snd (mul_ext_efficient_m fE xs ys m)) f
∧ fst (mul_ext_efficient_m fE xs ys m) = mul_ext_impl (λx y. f (x, y)) xs ys"
"(⋀m. model_P model m f ⟹
(⋀x z. x ∈ set (xs @ xs') ⟹ z ∈ set (y # ys) ⟹
fst (fE x z m) = f (x, z) ∧ model_P model (snd (fE x z m)) f)) ⟹
model_P model m f ⟹ model_P model (snd (mul_ex_dom_efficient_m fE xs xs' y ys m)) f
∧ fst (mul_ex_dom_efficient_m fE xs xs' y ys m) = mul_ex_dom (λx y. f (x, y)) xs xs' y ys"
for xs xs' y ys
proof (induct fE xs ys m and fE xs xs' y ys m rule: mul_ext_efficient_m_mul_ex_dom_efficient_m.induct)
case (6 fE x xs xs' y ys m)
have "model_P model (snd (fE x y m)) f ∧ fst (fE x y m) = f (x, y)" using 6(6,7) by auto
then obtain s ns m' where [simp]: "fE x y m = ((s, ns), m')" "model_P model m' f" "f (x, y) = (s, ns)"
by (metis prod.collapse)
have "s ⟹ model_P model (snd (filter_not_stri_efficient_m (fE x) ys m')) f ∧
fst (filter_not_stri_efficient_m (fE x) ys m') = [y←ys . ¬ fst (f (x, y))]"
using 6(6) by (intro filter_not_stri_efficient_m_sound) auto
then obtain ys' m2 where [simp]: "s ⟹ filter_not_stri_efficient_m (fE x) ys m' = (ys', m2)"
"s ⟹ model_P model m2 f" and ys'[simp]: "s ⟹ [y←ys . ¬ fst (f (x, y))] = ys'" by (metis prod.collapse)
have "s ⟹ set ys' ⊆ set ys" unfolding ys'[symmetric] by (auto simp del: ys')
then have "s ⟹ model_P model (snd (mul_ext_efficient_m fE (xs @ xs') ys' m2)) f ∧
fst (mul_ext_efficient_m fE (xs @ xs') ys' m2) = mul_ext_impl (λx y. f (x, y)) (xs @ xs') ys'"
using 6(6) by (intro 6(1)[OF r p p _ r p, of m', simplified]) auto
then obtain s' ns' m3 where [simp]: "s ⟹ mul_ext_efficient_m fE (xs @ xs') ys' m2 = ((s', ns'), m3)"
"s ⟹ mul_ext_impl (λx y. f (x, y)) (xs @ xs') ys' = (s', ns')"
"s ⟹ model_P model m3 f" "s ⟹ s' ⟹ ns'" by (metis prod.collapse mul_ext_impl_s_imp_ns)
have x: "s ⟹ ¬ ns' ⟹ model_P model (snd (mul_ex_dom_efficient_m fE xs (x # xs') y ys m3)) f ∧
fst (mul_ex_dom_efficient_m fE xs (x # xs') y ys m3) = mul_ex_dom (λx y. f (x, y)) xs (x # xs') y ys"
using 6(6) by (intro 6(2)[OF r p p _ r p p p p, of m']) auto
have "¬ s ⟹ ns ⟹ model_P model (snd (mul_ext_efficient_m fE (xs @ xs') ys m')) f ∧
fst (mul_ext_efficient_m fE (xs @ xs') ys m') = mul_ext_impl (λx y. f (x, y)) (xs @ xs') ys"
using 6(6) by (intro 6(3)[OF r p p, simplified]) auto
then obtain s2 ns2 m4 where [simp]: "¬ s ⟹ ns ⟹ mul_ext_efficient_m fE (xs @ xs') ys m' = ((s2, ns2), m4)"
"¬ s ⟹ ns ⟹ model_P model m4 f" "¬ s ⟹ ns ⟹ mul_ext_impl (λx y. f (x, y)) (xs @ xs') ys = (s2, ns2)"
"¬ s ⟹ ns ⟹ s2 ⟹ ns2" by (metis prod.collapse mul_ext_impl_s_imp_ns)
have "¬ s ⟹ ns ⟹ ¬ s2 ⟹ model_P model (snd (mul_ex_dom_efficient_m fE xs (x # xs') y ys m4)) f ∧
fst (mul_ex_dom_efficient_m fE xs (x # xs') y ys m4) = mul_ex_dom (λx y. f (x, y)) xs (x # xs') y ys"
using 6(6) by (intro 6(4)[OF r p p _ _ r p p, of m']) auto
then obtain s3 ns3 m5 where [simp]: "¬ s ⟹ ns ⟹ ¬ s2 ⟹ mul_ex_dom_efficient_m fE xs (x # xs') y ys m4 = ((s3, ns3), m5)"
"¬ s ⟹ ns ⟹ ¬ s2 ⟹ mul_ex_dom (λx y. f (x, y)) xs (x # xs') y ys = (s3, ns3)"
"¬ s ⟹ ns ⟹ ¬ s2 ⟹ model_P model m5 f"
"¬ s ⟹ ns ⟹ ¬ s2 ⟹ s3 ⟹ ns3" by (metis prod.collapse mul_ex_dom_s_imp_ns)
have y: "¬ s ⟹ ¬ ns ⟹ model_P model (snd (mul_ex_dom_efficient_m fE xs (x # xs') y ys m')) f ∧
fst (mul_ex_dom_efficient_m fE xs (x # xs') y ys m') = mul_ex_dom (λx y. f (x, y)) xs (x # xs') y ys"
using 6(6) by (intro 6(5)[OF r p p, simplified]) auto
show ?case unfolding mul_ex_dom_efficient_m.simps(2) mul_ex_dom.simps(2)
using x y by simp
qed (auto simp: *)
then show ?thesis using assms by simp
qed
lemma m_rpo_valid_sound:
assumes "m_rpo_valid pr tag m"
and "memory.lookup model m (p,q) = Some v"
shows "rpo_unbounded_impl pr tag p q = v"
using assms lookup_valid[of m "λp. rpo_unbounded_impl pr tag (fst p) (snd p)"]
unfolding m_rpo_valid_def valid_def by (cases v) auto
lemma store_rpo_sound :
assumes "m_rpo_valid pr tag m"
and "rpo_unbounded_impl pr tag s t = v"
shows "m_rpo_valid pr tag (memory.store model m ((s,t),v))"
using assms store_valid[of m "λp. rpo_unbounded_impl pr tag (fst p) (snd p)"]
unfolding m_rpo_valid_def by auto
lemma rpo_efficient_sound:
assumes "m_rpo_valid pr tag m"
shows "m_rpo_valid pr tag (snd (rpo_efficient pr tag p q m))
∧ fst (rpo_efficient pr tag p q m) = rpo_unbounded_impl pr tag p q"
proof (cases "memory.lookup model m (p, q)")
case (Some v) thus ?thesis using assms m_rpo_valid_sound by simp
next
case None thus ?thesis using assms
proof (induct p arbitrary: q m)
case (Var x q m) thus ?case using store_rpo_sound by (cases q) auto
next
case (Fun f ss q m) note IH = this
{
fix s m assume s_in_ss: "s ∈ set ss" and m_valid: "m_rpo_valid pr tag m"
have "fst (rpo_efficient pr tag s q m) = rpo_unbounded_impl pr tag s q
∧ m_rpo_valid pr tag (snd (rpo_efficient pr tag s q m))"
proof (cases "memory.lookup model m (s, q)")
case (Some v) thus ?thesis using m_valid m_rpo_valid_sound by simp
next
case None from IH(1)[OF s_in_ss None m_valid] show ?thesis by simp
qed
}
hence rec: "⋀s m. s ∈ set ss ⟹ m_rpo_valid pr tag m ⟹
fst (rpo_efficient pr tag s q m) = rpo_unbounded_impl pr tag s q
∧ m_rpo_valid pr tag (snd (rpo_efficient pr tag s q m))" by simp
thus ?case using IH(2) IH(3)
proof (induct q arbitrary: m)
case (Var y m) note Hq = this
obtain v m' where any_ns: "any_nstri_efficient_m (λs. rpo_efficient pr tag s (Var y))
ss m = (v, m')" by (cases "any_nstri_efficient_m (λs. rpo_efficient pr tag s (Var y)) ss m") auto
with any_nstri_efficient_m_sound[of ss "λf M. model_P model M (λp. f (fst p) (snd p))",
OF _ Hq(3)[unfolded m_rpo_valid_def], of "λs. rpo_efficient pr tag s (Var y)" "Var y"] Hq(1)
have any_ns': "(∃s∈set ss. snd (rpo_unbounded_impl pr tag s (Var y))) = v"
and m'_valid: "m_rpo_valid pr tag m'" unfolding m_rpo_valid_def by auto
show ?case using Hq(2) any_ns any_ns' m'_valid store_rpo_sound by simp
next
case (Fun g ts) note Hq = this
obtain any m' where any_ns: "any_nstri_efficient_m (λs. rpo_efficient pr tag s (Fun g ts))
ss m = (any, m')"
by (cases "any_nstri_efficient_m (λs. rpo_efficient pr tag s (Fun g ts)) ss m") auto
with any_nstri_efficient_m_sound[of ss "λf M. model_P model M (λp. f (fst p) (snd p))",
OF _ Hq(4)[unfolded m_rpo_valid_def], of "λs. rpo_efficient pr tag s (Fun g ts)"] Hq(2)
have any_ns': "(∃s∈set ss. snd (rpo_unbounded_impl pr tag s (Fun g ts))) = any"
and m'_valid: "m_rpo_valid pr tag m'" unfolding m_rpo_valid_def by auto
show ?case
proof (cases any)
case True note Hany = this
thus ?thesis using Hq(3) Hq(4) any_ns any_ns' m'_valid store_rpo_sound by simp
next
case False note Hany = this
let ?m = "length ss"
let ?n = "length ts"
obtain s ns where Hpr: "fst pr (f, ?m) (g,?n) = (s, ns)" by force
show ?thesis
proof (cases ns)
case False with Hq(3) any_ns any_ns' Hany Hpr m'_valid store_rpo_sound show ?thesis by simp
next
case True note Hns = this
obtain all m2 where all_s: "all_stri_efficient_m (rpo_efficient_m model pr tag
(Fun f ss)) ts m' = (all, m2)"
by (cases "all_stri_efficient_m (rpo_efficient_m model pr tag (Fun f ss)) ts m'") auto
{
fix t m
assume t_in_ts: "t ∈ set ts" and m_valid: "m_rpo_valid pr tag m"
have "fst (rpo_efficient pr tag (Fun f ss) t m) = rpo_unbounded_impl pr tag (Fun f ss) t
∧ m_rpo_valid pr tag (snd (rpo_efficient pr tag (Fun f ss) t m))"
proof (cases "memory.lookup model m (Fun f ss, t)")
case (Some v) thus ?thesis using m_valid m_rpo_valid_sound by simp
next
case None
{
fix s m'
assume s_in_ss: "s ∈ set ss" and m'_valid: "m_rpo_valid pr tag m'"
have "fst (rpo_efficient pr tag s t m') = rpo_unbounded_impl pr tag s t ∧
m_rpo_valid pr tag (snd (rpo_efficient pr tag s t m'))"
proof (cases "memory.lookup model m' (s, t)")
case (Some v) thus ?thesis using m'_valid m_rpo_valid_sound by simp
next
case None from IH(1)[OF s_in_ss None m'_valid] show ?thesis by simp
qed
}
with Hq(1)[OF t_in_ts _ None m_valid] IH(1) show ?thesis by simp
qed
}
with all_stri_efficient_m_sound[of ts "λf M. model_P model M (λp. f (fst p) (snd p))",
OF _ m'_valid[unfolded m_rpo_valid_def], of "rpo_efficient pr tag (Fun f ss)"] all_s
have all_s': "(∀t∈set ts. fst (rpo_unbounded_impl pr tag (Fun f ss) t)) = all"
and m2_valid: "m_rpo_valid pr tag m2" unfolding m_rpo_valid_def by auto
show ?thesis
proof (cases s)
case True
with Hq(3) any_ns any_ns' all_s all_s' Hany Hns Hpr m2_valid store_rpo_sound
show ?thesis by simp
next
case False note Hs = this
show ?thesis
proof (cases all)
case False note Hall = this
from Hq(3) any_ns any_ns' all_s all_s' Hall Hany Hns Hpr Hs store_rpo_sound
m2_valid show ?thesis by (simp add: all_s' Hall)
next
case True note Hall = this
let ?cf = "tag (f, ?m)"
let ?cg = "tag (g, ?n)"
show ?thesis
proof (cases "?cf = ?cg")
case False
with Hq(3) any_ns any_ns' all_s all_s' Hall Hany Hns Hs Hpr m2_valid store_rpo_sound
show ?thesis by (cases ts, simp_all)
next
case True note cfg = this
{
fix t s m
assume s_in_ss: "s ∈ set ss" and t_in_ts: "t ∈ set ts"
and m_valid: "m_rpo_valid pr tag m"
have "fst (rpo_efficient pr tag s t m) = rpo_unbounded_impl pr tag s t
∧ m_rpo_valid pr tag (snd (rpo_efficient pr tag s t m))"
proof (cases "memory.lookup model m (s, t)")
case (Some v) thus ?thesis using m_valid m_rpo_valid_sound by simp
next
case None from IH(1)[OF s_in_ss None m_valid] show ?thesis by simp
qed
} note rec = this
show ?thesis
proof (cases ?cf)
case Mul note cf = this
obtain v m3 where mext: "mul_ext_efficient_m (rpo_efficient pr tag) ss ts m2
= (v, m3)" by (cases "mul_ext_efficient_m (rpo_efficient pr tag) ss ts m2") auto
from rpo_unbounded_impl_sound[of "pr" tag] rpo_unbounded_stri_imp_nstri[of "pr" tag]
have Himp: "∀ x y. fst (rpo_unbounded_impl pr tag x y) ⟶ snd (rpo_unbounded_impl
pr tag x y)" by metis
from mul_ext_efficient_m_sound[of ss ts "λp. rpo_unbounded_impl pr tag (fst p) (snd p)"
"rpo_efficient pr tag" m2] Himp m2_valid[unfolded m_rpo_valid_def] mext rec
have mext': "mul_ext_impl (rpo_unbounded_impl pr tag) ss ts = v"
and m3_valid: "m_rpo_valid pr tag m3" unfolding m_rpo_valid_def by auto
with Hq(3) any_ns any_ns' all_s all_s' Hall Hany Hns Hs Hpr cfg cf mext
and store_rpo_sound show ?thesis unfolding mul_ext_impl_sound by simp
next
case Lex note cf = this
obtain v m3 where lext: "lex_ext_efficient_m (rpo_efficient pr tag) ss ts m2
= (v, m3)" by (cases "lex_ext_efficient_m (rpo_efficient pr tag) ss ts m2") auto
from lex_ext_efficient_m_sound[OF _ m2_valid[unfolded m_rpo_valid_def],
of ss ts "rpo_efficient pr tag"] lext rec
have lext': "lex_ext_unbounded (rpo_unbounded_impl pr tag) ss ts = v"
and m3_valid: "m_rpo_valid pr tag m3" unfolding m_rpo_valid_def by auto
with Hq(3) any_ns any_ns' all_s all_s' Hall Hany Hns Hs Hpr cfg cf lext
and store_rpo_sound show ?thesis by simp
qed
qed
qed
qed
qed
qed
qed
qed
qed
definition memoized_rpo where
"memoized_rpo pr tag p q ≡ fst (rpo_efficient pr tag p q (memory.empty model ()))"
lemma memoized_rpo_sound:
"memoized_rpo = rpo_unbounded_impl"
proof-
{
fix "pr" tag p q
from rpo_efficient_sound[of "pr" tag "memory.empty model ()"]
model_satisfactory[unfolded satisfactory_def]
have "memoized_rpo pr tag p q = rpo_unbounded_impl pr tag p q"
unfolding m_rpo_valid_def memoized_rpo_def
by simp
} thus ?thesis by (rule_tac HOL.ext)+
qed
end
global_interpretation memoized_rpo_1 : memoized_rpo lm valid
defines efficient_rpo_1 = memoized_rpo_1.memoized_rpo
using satisfactory_lm by unfold_locales (auto simp: efficient_rpo_1_def)
theorem rpo_efficient_1_sound: "rpo_unbounded_impl = efficient_rpo_1"
by (simp add: memoized_rpo_1.memoized_rpo_sound efficient_rpo_1_def)
global_interpretation memoized_rpo_2 : memoized_rpo l2m l2m_valid
defines efficient_rpo_2 = memoized_rpo_2.memoized_rpo
using satisfactory_l2m by (unfold_locales) (simp_all add: efficient_rpo_2_def)
theorem rpo_efficient_2_sound: "rpo_unbounded_impl = efficient_rpo_2"
by (simp add: memoized_rpo_2.memoized_rpo_sound)
declare rpo_efficient_2_sound[code]
end