Theory First_Order_Terms.Subterm_and_Context
section ‹Subterms and Contexts›
text ‹
We define the (proper) sub- and superterm relations on first order terms,
as well as contexts (you can think of contexts as terms with exactly one hole,
where we can plug-in another term).
Moreover, we establish several connections between these concepts as well as
to other concepts such as substitutions.
›
theory Subterm_and_Context
imports
Term
"Abstract-Rewriting.Abstract_Rewriting"
begin
subsection ‹Subterms›
text ‹The ∗‹superterm› relation.›
inductive_set
supteq :: "(('f, 'v) term × ('f, 'v) term) set"
where
refl [simp, intro]: "(t, t) ∈ supteq" |
subt [intro]: "u ∈ set ss ⟹ (u, t) ∈ supteq ⟹ (Fun f ss, t) ∈ supteq"
text ‹The ∗‹proper superterm› relation.›
inductive_set
supt :: "(('f, 'v) term × ('f, 'v) term) set"
where
arg [simp, intro]: "s ∈ set ss ⟹ (Fun f ss, s) ∈ supt" |
subt [intro]: "s ∈ set ss ⟹ (s, t) ∈ supt ⟹ (Fun f ss, t) ∈ supt"
hide_const suptp supteqp
hide_fact
suptp.arg suptp.cases suptp.induct suptp.intros suptp.subt suptp_supt_eq
hide_fact
supteqp.cases supteqp.induct supteqp.intros supteqp.refl supteqp.subt supteqp_supteq_eq
hide_fact (open) supt.arg supt.subt supteq.refl supteq.subt
subsubsection ‹Syntactic Sugar›
text ‹Infix syntax.›
abbreviation "supt_pred s t ≡ (s, t) ∈ supt"
abbreviation "supteq_pred s t ≡ (s, t) ∈ supteq"
abbreviation (input) "subt_pred s t ≡ supt_pred t s"
abbreviation (input) "subteq_pred s t ≡ supteq_pred t s"
notation
supt (‹{⊳}›) and
supt_pred (‹(_/ ⊳ _)› [56, 56] 55) and
subt_pred (infix ‹⊲› 55) and
supteq (‹{⊵}›) and
supteq_pred (‹(_/ ⊵ _)› [56, 56] 55) and
subteq_pred (infix ‹⊴› 55)
abbreviation subt (‹{⊲}›) where "{⊲} ≡ {⊳}¯"
abbreviation subteq (‹{⊴}›) where "{⊴} ≡ {⊵}¯"
text ‹Quantifier syntax.›
syntax
"_All_supteq" :: "[idt, 'a, bool] ⇒ bool" (‹(3∀_⊵_./ _)› [0, 0, 10] 10)
"_Ex_supteq" :: "[idt, 'a, bool] ⇒ bool" (‹(3∃_⊵_./ _)› [0, 0, 10] 10)
"_All_supt" :: "[idt, 'a, bool] ⇒ bool" (‹(3∀_⊳_./ _)› [0, 0, 10] 10)
"_Ex_supt" :: "[idt, 'a, bool] ⇒ bool" (‹(3∃_⊳_./ _)› [0, 0, 10] 10)
"_All_subteq" :: "[idt, 'a, bool] ⇒ bool" (‹(3∀_⊴_./ _)› [0, 0, 10] 10)
"_Ex_subteq" :: "[idt, 'a, bool] ⇒ bool" (‹(3∃_⊴_./ _)› [0, 0, 10] 10)
"_All_subt" :: "[idt, 'a, bool] ⇒ bool" (‹(3∀_⊲_./ _)› [0, 0, 10] 10)
"_Ex_subt" :: "[idt, 'a, bool] ⇒ bool" (‹(3∃_⊲_./ _)› [0, 0, 10] 10)
syntax_consts
"_All_supteq" "_All_supt" "_All_subteq" "_All_subt" ⇌ All and
"_Ex_supteq" "_Ex_supt" "_Ex_subteq" "_Ex_subt" ⇌ Ex
translations
"∀x⊵y. P" ⇀ "∀x. x ⊵ y ⟶ P"
"∃x⊵y. P" ⇀ "∃x. x ⊵ y ∧ P"
"∀x⊳y. P" ⇀ "∀x. x ⊳ y ⟶ P"
"∃x⊳y. P" ⇀ "∃x. x ⊳ y ∧ P"
"∀x⊴y. P" ⇀ "∀x. x ⊴ y ⟶ P"
"∃x⊴y. P" ⇀ "∃x. x ⊴ y ∧ P"
"∀x⊲y. P" ⇀ "∀x. x ⊲ y ⟶ P"
"∃x⊲y. P" ⇀ "∃x. x ⊲ y ∧ P"
print_translation ‹
let
val All_binder = Mixfix.binder_name @{const_syntax All};
val Ex_binder = Mixfix.binder_name @{const_syntax Ex};
val impl = @{const_syntax "implies"};
val conj = @{const_syntax "conj"};
val supt = @{const_syntax "supt_pred"};
val supteq = @{const_syntax "supteq_pred"};
val trans =
[((All_binder, impl, supt), ("_All_supt", "_All_subt")),
((All_binder, impl, supteq), ("_All_supteq", "_All_subteq")),
((Ex_binder, conj, supt), ("_Ex_supt", "_Ex_subt")),
((Ex_binder, conj, supteq), ("_Ex_supteq", "_Ex_subteq"))];
fun matches_bound v t =
case t of (Const ("_bound", _) $ Free (v', _)) => (v = v')
| _ => false
fun contains_var v = Term.exists_subterm (fn Free (x, _) => x = v | _ => false)
fun mk x c n P = Syntax.const c $ Syntax_Trans.mark_bound_body x $ n $ P
fun tr' q = (q,
K (fn [Const ("_bound", _) $ Free (v, T), Const (c, _) $ (Const (d, _) $ t $ u) $ P] =>
(case AList.lookup (=) trans (q, c, d) of
NONE => raise Match
| SOME (l, g) =>
if matches_bound v t andalso not (contains_var v u) then mk (v, T) l u P
else if matches_bound v u andalso not (contains_var v t) then mk (v, T) g t P
else raise Match)
| _ => raise Match));
in [tr' All_binder, tr' Ex_binder] end
›
subsubsection ‹Transitivity Reasoning for Subterms›
lemma supt_trans [trans]:
"s ⊳ t ⟹ t ⊳ u ⟹ s ⊳ u"
by (induct s t rule: supt.induct) auto
lemma trans_supt: "trans {⊳}" by (auto simp: trans_def dest: supt_trans)
lemma supteq_trans [trans]:
"s ⊵ t ⟹ t ⊵ u ⟹ s ⊵ u"
by (induct s t rule: supteq.induct) (auto)
text ‹Auxiliary lemmas about term size.›
lemma size_simp5:
"s ∈ set ss ⟹ s ⊳ t ⟹ size t < size s ⟹ size t < Suc (size_list size ss)"
by (induct ss) auto
lemma size_simp6:
"s ∈ set ss ⟹ s ⊵ t ⟹ size t ≤ size s ⟹ size t ≤ Suc (size_list size ss)"
by (induct ss) auto
lemma size_simp1:
"t ∈ set ts ⟹ size t < Suc (size_list size ts)"
by (induct ts) auto
lemma size_simp2:
"t ∈ set ts ⟹ size t < Suc (Suc (size s + size_list size ts))"
by (induct ts) auto
lemma size_simp3:
assumes "(x, y) ∈ set (zip xs ys)"
shows "size x < Suc (size_list size xs)"
using set_zip_leftD [OF assms] size_simp1 by auto
lemma size_simp4:
assumes "(x, y) ∈ set (zip xs ys)"
shows "size y < Suc (size_list size ys)"
using set_zip_rightD [OF assms] using size_simp1 by auto
lemmas size_simps =
size_simp1 size_simp2 size_simp3 size_simp4 size_simp5 size_simp6
declare size_simps [termination_simp]
lemma supt_size:
"s ⊳ t ⟹ size s > size t"
by (induct rule: supt.induct) (auto simp: size_simps)
lemma supteq_size:
"s ⊵ t ⟹ size s ≥ size t"
by (induct rule: supteq.induct) (auto simp: size_simps)
text ‹Reflexivity and Asymmetry.›
lemma reflcl_supteq [simp]:
"supteq⇧= = supteq" by auto
lemma trancl_supteq [simp]:
"supteq⇧+ = supteq"
by (rule trancl_id) (auto simp: trans_def intro: supteq_trans)
lemma rtrancl_supteq [simp]:
"supteq⇧* = supteq"
unfolding trancl_reflcl[symmetric] by auto
lemma eq_supteq: "s = t ⟹ s ⊵ t" by auto
lemma supt_neqD: "s ⊳ t ⟹ s ≠ t" using supt_size by auto
lemma supteq_Var [simp]:
"x ∈ vars_term t ⟹ t ⊵ Var x"
proof (induct t)
case (Var y) then show ?case by (cases "x = y") auto
next
case (Fun f ss) then show ?case by (auto)
qed
lemmas vars_term_supteq = supteq_Var
lemma term_not_arg [iff]:
"Fun f ss ∉ set ss" (is "?t ∉ set ss")
proof
assume "?t ∈ set ss"
then have "?t ⊳ ?t" by (auto)
then have "?t ≠ ?t" by (auto dest: supt_neqD)
then show False by simp
qed
lemma supt_Fun [simp]:
assumes "s ⊳ Fun f ss" (is "s ⊳ ?t") and "s ∈ set ss"
shows "False"
proof -
from ‹s ∈ set ss› have "?t ⊳ s" by (auto)
then have "size ?t > size s" by (rule supt_size)
from ‹s ⊳ ?t› have "size s > size ?t" by (rule supt_size)
with ‹size ?t > size s› show False by simp
qed
lemma supt_supteq_conv: "s ⊳ t = (s ⊵ t ∧ s ≠ t)"
proof
assume "s ⊳ t" then show "s ⊵ t ∧ s ≠ t"
proof (induct rule: supt.induct)
case (subt s ss t f)
have "s ⊵ s" ..
from ‹s ∈ set ss› have "Fun f ss ⊵ s" by (auto)
from ‹s ⊵ t ∧ s ≠ t› have "s ⊵ t" ..
with ‹Fun f ss ⊵ s› have first: "Fun f ss ⊵ t" by (rule supteq_trans)
from ‹s ∈ set ss› and ‹s ⊳ t› have "Fun f ss ⊳ t" ..
then have second: "Fun f ss ≠ t" by (auto dest: supt_neqD)
from first and second show "Fun f ss ⊵ t ∧ Fun f ss ≠ t" by auto
qed (auto simp: size_simps)
next
assume "s ⊵ t ∧ s ≠ t"
then have "s ⊵ t" and "s ≠ t" by auto
then show "s ⊳ t" by (induct) (auto)
qed
lemma supt_not_sym: "s ⊳ t ⟹ ¬ (t ⊳ s)"
proof
assume "s ⊳ t" and "t ⊳ s" then have "s ⊳ s" by (rule supt_trans)
then show False unfolding supt_supteq_conv by simp
qed
lemma supt_irrefl[iff]: "¬ t ⊳ t"
using supt_not_sym[of t t] by auto
lemma irrefl_subt: "irrefl {⊲}" by (auto simp: irrefl_def)
lemma supt_imp_supteq: "s ⊳ t ⟹ s ⊵ t"
unfolding supt_supteq_conv by auto
lemma supt_supteq_not_supteq: "s ⊳ t = (s ⊵ t ∧ ¬ (t ⊵ s))"
using supt_not_sym unfolding supt_supteq_conv by auto
lemma supteq_supt_conv: "(s ⊵ t) = (s ⊳ t ∨ s = t)" by (auto simp: supt_supteq_conv)
lemma supteq_antisym:
assumes "s ⊵ t" and "t ⊵ s" shows "s = t"
using assms unfolding supteq_supt_conv by (auto simp: supt_not_sym)
text ‹The subterm relation is an order on terms.›