Theory RPO_Mem_Impl
section ‹A Memoized Implementation of RPO›
text ‹We derive a memoized RPO implementation from the memoized WPO implementation›
theory RPO_Mem_Impl
imports
RPO_Unbounded
WPO_Mem_Impl
begin
definition rpo_mem :: "('f × nat ⇒ 'f × nat ⇒ bool × bool) × ('f × nat ⇒ bool)
⇒ ('f × nat ⇒ order_tag) ⇒ _" where
[code del]: "rpo_mem pr c mem st =
wpo_mem (fst pr) (snd pr) False (λ _. False) (λ _ _. False) (λ _ _. True) full_status c mem st"
definition rpo_main :: "('f × nat ⇒ 'f × nat ⇒ bool × bool) × ('f × nat ⇒ bool)
⇒ ('f × nat ⇒ order_tag) ⇒ _" where
[code del]: "rpo_main pr c mem st =
wpo_main (fst pr) (snd pr) False (λ _. False) (λ _ _. False) (λ _ _. True) full_status c mem st"
lemma rpo_mem_code[code]: "rpo_mem pr c mem (s,t) =
(let
i = index s;
j = index t
in
(case Mapping.lookup mem (i,j) of
Some res ⇒ (res, mem)
| None ⇒ case rpo_main pr c mem (s,t)
of (res, mem_new) ⇒ (res, Mapping.update (i,j) res mem_new)))"
unfolding rpo_mem_def rpo_main_def wpo_mem.simps ..
lemma rpo_main_code[code]: "rpo_main pr c mem (s,t) = (case s of
Var x ⇒ ((False,
(case t of
Var y ⇒ name_of x = name_of y
| Fun g ts ⇒ ts = [] ∧ snd pr (name_of g, 0))), mem)
| Fun f ss ⇒
let ff = (name_of f, length ss) in
(case exists_mem (λ s'. (s',t)) (rpo_mem pr c) snd mem ss of
(sub_result, mem_out_1) ⇒
if sub_result then ((True, True), mem_out_1)
else
(case t of
Var _ ⇒ ((False, False), mem_out_1)
| Fun g ts ⇒
let gg = (name_of g, length ts) in
(case fst pr ff gg of (prs, prns) ⇒
if prns then
(case forall_mem (λ t'. (s,t')) (rpo_mem pr c) fst mem_out_1 ts of
(sub_result, mem_out_2) ⇒
if sub_result then
if prs then ((True, True), mem_out_2)
else
let cf = c ff; cg = c gg in
if cf = Lex ∧ cg = Lex then lex_ext_unbounded_mem (rpo_mem pr c) mem_out_2 ss ts
else if cf = Mul ∧ cg = Mul then mul_ext_mem (rpo_mem pr c) mem_out_2 ss ts
else if ts = [] then ((ss ≠ [], True), mem_out_2)
else ((False, False), mem_out_2)
else ((False, False), mem_out_2)) else ((False,False), mem_out_1))
)
)
)"
unfolding rpo_main_def rpo_mem_def wpo_main.simps Let_def if_False if_True
unfolding rpo_main_def[symmetric] rpo_mem_def[symmetric]
by (cases s; cases t, auto simp: map_nth split: prod.splits)
declare [[code drop: rpo_unbounded]]
lemma rpo_unbounded_memoized_code[code]: "rpo_unbounded pr c s t = fst (rpo_mem pr c Mapping.empty (index_term s, index_term t))"
unfolding rpo_mem_def wpo_mem_impl_def[symmetric] wpo_ub_memoized_code[symmetric]
proof (induct pr c s t rule: rpo_unbounded.induct)
case (1 pr c x y)
then show ?case unfolding rpo_unbounded.simps wpo_ub.simps[of _ _ _ _ _ _ _ _ "Var x" "Var y"]
by simp
next
case (2 pr c x g ts)
then show ?case unfolding rpo_unbounded.simps wpo_ub.simps[of _ _ _ _ _ _ _ _ "Var x" "Fun g ts"] term.simps
by auto
next
case (3 pr c f ss y)
then show ?case unfolding rpo_unbounded.simps wpo_ub.simps[of _ _ _ _ _ _ _ _ "Fun f ss" "Var y"] term.simps
Let_def by (auto simp: set_conv_nth)
next
case (4 pr c f ss g ts)
obtain prs prns where pr: "fst pr (f, length ss) (g, length ts) = (prs,prns)" by force
show ?case unfolding rpo_unbounded.simps wpo_ub.simps[of _ _ _ _ _ _ _ _ "Fun f ss" "Fun g ts"] term.simps
if_False Let_def if_True pr split
proof (rule sym, intro if_cong[OF _ refl if_cong[OF _ if_cong[OF refl refl] refl]], goal_cases)
case 1
show ?case using 4(1) by (auto simp: set_conv_nth)
next
case 2
show ?case using 4(2)[unfolded pr, OF 2 refl] by (auto simp: set_conv_nth)
next
case 3
note IH = 4(3-)[unfolded pr, OF 3(1) refl 3(2-3)]
let ?cf = "c (f, length ss)"
let ?cg = "c (g, length ts)"
consider (Lex) "?cf = Lex" "?cg = Lex" | (Mul) "?cf = Mul" "?cg = Mul" | (Diff) "?cf ≠ ?cg"
by (cases ?cf; cases ?cg, auto)
thus ?case
proof cases
case Lex
hence "?cf = ?cg" and "?cf ≠ Mul" by auto
note IH = IH(2)[OF this]
from Lex have id: "(?cf = Lex ∧ ?cg = Lex) = True" "(?cf = ?cg) = True" "(?cf = Mul) = False" by auto
show ?thesis unfolding id if_True if_False using IH
by (intro lex_ext_unbounded_cong, auto intro: nth_equalityI)
next
case Mul
hence "?cf = ?cg" and "?cf = Mul" by auto
note IH = IH(1)[OF this]
from Mul have id: "(?cf = Lex ∧ ?cg = Lex) = False" "(?cf = Mul ∧ ?cg = Mul) = True"
"(?cf = ?cg) = True" "(?cf = Mul) = True" by auto
show ?thesis unfolding id(1-3) if_True if_False unfolding id(4) if_True using IH
by (intro mul_ext_cong[OF arg_cong[of _ _ mset] arg_cong[of _ _ mset]])
(auto intro: nth_equalityI)
qed auto
qed
qed
end