Theory TA_Impl_Misc
theory TA_Impl_Misc
imports Main
begin
subsection ‹Invariants on folds›
lemma fold_acc_preserv:
assumes "⋀ x acc. P acc ⟹ P (f x acc)" "P acc"
shows "P (fold f xs acc)"
using assms(2) by (induction xs arbitrary: acc) (auto intro: assms(1))
lemma fold_acc_preserv':
assumes "⋀ x acc. x ∈ set xs ⟹ P acc ⟹ P (f x acc)" "P acc"
shows "P (fold f xs acc)"
using assms by (induction xs arbitrary: acc) auto
lemma fold_acc_ev_preserv':
fixes x
assumes
"⋀ x acc. P acc ⟹ P (f x acc)" "⋀ x acc. Q acc ⟹ Q (f x acc)"
"⋀ acc. Q acc ⟹ P (f x acc)" "x ∈ set xs" "Q acc"
shows "P (fold f xs acc) ∧ Q (fold f xs acc)"
using assms(4,5) apply (induction xs arbitrary: acc)
using assms(1,2,3) by (auto intro: fold_acc_preserv)
lemma fold_acc_ev_preserv:
fixes x
assumes
"⋀ x acc. P acc ⟹ Q acc ⟹ P (f x acc)" "⋀ x acc. Q acc ⟹ Q (f x acc)"
"⋀ acc. Q acc ⟹ P (f x acc)" "x ∈ set xs" "Q acc"
shows "P (fold f xs acc) ∧ Q (fold f xs acc)"
apply (rule fold_acc_ev_preserv'[where P = "λ acc. P acc ∧ Q acc" and Q = Q, THEN conjunct1])
by (auto intro: assms)
lemmas fold_ev_preserv = fold_acc_ev_preserv[where Q = "λ _. True", simplified]
lemma fold_evD':
assumes "¬ P acc" "P (fold f xs acc)"
shows "∃ x ys zs. xs = ys @ x # zs ∧ ¬ P (fold f ys acc) ∧ P (f x (fold f ys acc))"
using assms
apply (induction xs arbitrary: acc)
apply (simp; fail)
subgoal premises prems for x xs acc
apply (cases "P (f x acc)")
using prems(2-) apply fastforce
apply (drule prems(1))
using prems apply simp
apply clarsimp
subgoal for xa ys zs
apply (rule exI[where x = xa])
apply (rule exI[where x = "x # ys"])
by fastforce
done
done
lemma fold_evD:
assumes
"P y (fold f xs acc)" "¬ P y acc" "⋀ acc x. ¬ P y acc ⟹ Q acc ⟹ P y (f x acc) ⟹ x = y"
"Q acc" "⋀ acc x. Q acc ⟹ Q (f x acc)" "⋀ acc x. ¬ P y acc ⟹ Q acc ⟹ P y (f x acc) ⟹ R y"
shows "∃ ys zs. xs = ys @ y # zs ∧ ¬ P y (fold f ys acc) ∧ P y (f y (fold f ys acc)) ∧ R y"
proof -
from fold_evD'[OF assms(2,1)] obtain x ys zs where *:
"xs = ys @ x # zs" "¬ P y (fold f ys acc)" "P y (f x (fold f ys acc))"
by auto
moreover from assms(4-) have "Q (fold f ys acc)" by (auto intro: fold_acc_preserv)
ultimately show ?thesis using assms(3,6) by auto
qed
lemmas fold_evD'' = fold_evD[where R = "λ _. True", simplified]
end