(* Title: Jinja/Compiler/Index.thy ID: $Id: Index.html 1910 2004-05-19 04:46:04Z kleing $ Author: Tobias Nipkow Copyright TUM 2003 *) header {* \isaheader{Indexing variables in variable lists} *} theory Index = Main: text{* In order to support local variables and arbitrarily nested blocks, the local variables are arranged as an indexed list. The outermost local variable (``this'') is the first element in the list, the most recently created local variable the last element. When descending into a block structure, a corresponding list @{term Vs} of variable names is maintained. To find the index of some variable @{term V}, we have to find the index of the \emph{last} occurrence of @{term V} in @{term Vs}. This is what @{term index} does: *} consts index :: "'a list => 'a => nat" primrec "index [] y = 0" "index (x#xs) y = (if x=y then if x ∈ set xs then index xs y + 1 else 0 else index xs y + 1)" constdefs hidden :: "'a list => nat => bool" "hidden xs i ≡ i < size xs ∧ xs!i ∈ set(drop (i+1) xs)" subsection {* @{term index} *} lemma [simp]: "index (xs @ [x]) x = size xs" (*<*)by(induct xs) simp_all(*>*) lemma [simp]: "(index (xs @ [x]) y = size xs) = (x = y)" (*<*)by(induct xs) auto(*>*) lemma [simp]: "x ∈ set xs ==> xs ! index xs x = x" (*<*)by(induct xs) auto(*>*) lemma [simp]: "x ∉ set xs ==> index xs x = size xs" (*<*)by(induct xs) auto(*>*) lemma index_size_conv[simp]: "(index xs x = size xs) = (x ∉ set xs)" (*<*)by(induct xs) auto(*>*) lemma size_index_conv[simp]: "(size xs = index xs x) = (x ∉ set xs)" (*<*)by(induct xs) auto(*>*) lemma "(index xs x < size xs) = (x ∈ set xs)" (*<*)by(induct xs) auto(*>*) lemma [simp]: "[| y ∈ set xs; x ≠ y |] ==> index (xs @ [x]) y = index xs y" (*<*)by(induct xs) auto(*>*) lemma index_less_size[simp]: "x ∈ set xs ==> index xs x < size xs" (*<*) apply(induct xs) apply simp apply(fastsimp) done (*>*) lemma index_less_aux: "[|x ∈ set xs; size xs ≤ n|] ==> index xs x < n" (*<*) apply(subgoal_tac "index xs x < size xs") apply(simp (no_asm_simp)) apply simp done (*>*) lemma [simp]: "x ∈ set xs ∨ y ∈ set xs ==> (index xs x = index xs y) = (x = y)" (*<*)by (induct xs) auto(*>*) lemma inj_on_index: "inj_on (index xs) (set xs)" (*<*)by(simp add:inj_on_def)(*>*) lemma index_drop: "!!x i. [| x ∈ set xs; index xs x < i |] ==> x ∉ set(drop i xs)" (*<*) apply(induct xs) apply (auto simp:drop_Cons split:split_if_asm nat.splits dest:in_set_dropD) done (*>*) subsection {* @{term hidden} *} lemma hidden_index: "x ∈ set xs ==> hidden (xs @ [x]) (index xs x)" (*<*) apply(auto simp add:hidden_def index_less_aux nth_append) apply(drule index_less_size) apply(simp del:index_less_size) done (*>*) lemma hidden_inacc: "hidden xs i ==> index xs x ≠ i" (*<*) apply(case_tac "x ∈ set xs") apply(auto simp add:hidden_def index_less_aux nth_append index_drop) done (*>*) lemma [simp]: "hidden xs i ==> hidden (xs@[x]) i" (*<*)by(auto simp add:hidden_def nth_append)(*>*) lemma fun_upds_apply: "!!m ys. (m(xs[\<mapsto>]ys)) x = (let xs' = take (size ys) xs in if x ∈ set xs' then Some(ys ! index xs' x) else m x)" (*<*) apply(induct xs) apply (simp add:Let_def) apply(case_tac ys) apply (simp add:Let_def) apply (simp add:Let_def) done (*>*) lemma map_upds_apply_eq_Some: "((m(xs[\<mapsto>]ys)) x = Some y) = (let xs' = take (size ys) xs in if x ∈ set xs' then ys ! index xs' x = y else m x = Some y)" (*<*)by(simp add:fun_upds_apply Let_def)(*>*) lemma map_upds_upd_conv_index: "[|x ∈ set xs; size xs ≤ size ys |] ==> m(xs[\<mapsto>]ys)(x\<mapsto>y) = m(xs[\<mapsto>]ys[index xs x := y])" (*<*) apply(rule ext) apply(simp add:fun_upds_apply index_less_aux eq_sym_conv Let_def) done (*>*) end
lemma
index (xs @ [x]) x = length xs
lemma
(index (xs @ [x]) y = length xs) = (x = y)
lemma
x : set xs ==> xs ! index xs x = x
lemma
x ~: set xs ==> index xs x = length xs
lemma index_size_conv:
(index xs x = length xs) = (x ~: set xs)
lemma size_index_conv:
(length xs = index xs x) = (x ~: set xs)
lemma
(index xs x < length xs) = (x : set xs)
lemma
[| y : set xs; x ~= y |] ==> index (xs @ [x]) y = index xs y
lemma index_less_size:
x : set xs ==> index xs x < length xs
lemma index_less_aux:
[| x : set xs; length xs <= n |] ==> index xs x < n
lemma
x : set xs | y : set xs ==> (index xs x = index xs y) = (x = y)
lemma inj_on_index:
inj_on (index xs) (set xs)
lemma index_drop:
[| x : set xs; index xs x < i |] ==> x ~: set (drop i xs)
lemma hidden_index:
x : set xs ==> hidden (xs @ [x]) (index xs x)
lemma hidden_inacc:
hidden xs i ==> index xs x ~= i
lemma
hidden xs i ==> hidden (xs @ [x]) i
lemma fun_upds_apply:
(m(xs [|->] ys)) x = (let xs' = take (length ys) xs in if x : set xs' then Some (ys ! index xs' x) else m x)
lemma map_upds_apply_eq_Some:
((m(xs [|->] ys)) x = Some y) = (let xs' = take (length ys) xs in if x : set xs' then ys ! index xs' x = y else m x = Some y)
lemma map_upds_upd_conv_index:
[| x : set xs; length xs <= length ys |] ==> m(xs [|->] ys, x |-> y) = m(xs [|->] ys[index xs x := y])