doc-src/TutorialI/Trie/Trie.thy
author chaieb
Wed, 19 May 2004 11:23:59 +0200
changeset 14758 af3b71a46a1c
parent 12328 7c4ec77a8715
child 15905 0a4cc9b113c7
permissions -rw-r--r--
A new implementation for presburger arithmetic following the one suggested in technical report Chaieb Amine and Tobias Nipkow. It is generic an smaller. the tactic has also changed and allows the abstaction over fuction occurences whose type is nat or int.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
     1
(*<*)
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
     2
theory Trie = Main:;
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
     3
(*>*)
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
     4
text{*
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
     5
To minimize running time, each node of a trie should contain an array that maps
10795
9e888d60d3e5 minor edits to Chapters 1-3
paulson
parents: 10171
diff changeset
     6
letters to subtries. We have chosen a
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
     7
representation where the subtries are held in an association list, i.e.\ a
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
     8
list of (letter,trie) pairs.  Abstracting over the alphabet @{typ"'a"} and the
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
     9
values @{typ"'v"} we define a trie as follows:
9458
c613cd06d5cf apply. -> by
nipkow
parents: 8771
diff changeset
    10
*};
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    11
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    12
datatype ('a,'v)trie = Trie  "'v option"  "('a * ('a,'v)trie)list";
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    13
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    14
text{*\noindent
11458
09a6c44a48ea numerous stylistic changes and indexing
paulson
parents: 11309
diff changeset
    15
\index{datatypes!and nested recursion}%
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    16
The first component is the optional value, the second component the
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    17
association list of subtries.  This is an example of nested recursion involving products,
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    18
which is fine because products are datatypes as well.
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    19
We define two selector functions:
9458
c613cd06d5cf apply. -> by
nipkow
parents: 8771
diff changeset
    20
*};
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    21
10171
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
    22
consts value :: "('a,'v)trie \<Rightarrow> 'v option"
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
    23
       alist :: "('a,'v)trie \<Rightarrow> ('a * ('a,'v)trie)list";
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    24
primrec "value(Trie ov al) = ov";
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    25
primrec "alist(Trie ov al) = al";
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    26
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    27
text{*\noindent
11309
d666f11ca2d4 minor suggestions by Tanja Vos
paulson
parents: 11303
diff changeset
    28
Association lists come with a generic lookup function.  Its result
d666f11ca2d4 minor suggestions by Tanja Vos
paulson
parents: 11303
diff changeset
    29
involves type @{text option} because a lookup can fail:
9458
c613cd06d5cf apply. -> by
nipkow
parents: 8771
diff changeset
    30
*};
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    31
10171
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
    32
consts   assoc :: "('key * 'val)list \<Rightarrow> 'key \<Rightarrow> 'val option";
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    33
primrec "assoc [] x = None"
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    34
        "assoc (p#ps) x =
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    35
           (let (a,b) = p in if a=x then Some b else assoc ps x)";
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    36
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    37
text{*
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    38
Now we can define the lookup function for tries. It descends into the trie
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    39
examining the letters of the search string one by one. As
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    40
recursion on lists is simpler than on tries, let us express this as primitive
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    41
recursion on the search string argument:
9458
c613cd06d5cf apply. -> by
nipkow
parents: 8771
diff changeset
    42
*};
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    43
10171
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
    44
consts   lookup :: "('a,'v)trie \<Rightarrow> 'a list \<Rightarrow> 'v option";
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    45
primrec "lookup t [] = value t"
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    46
        "lookup t (a#as) = (case assoc (alist t) a of
10171
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
    47
                              None \<Rightarrow> None
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
    48
                            | Some at \<Rightarrow> lookup at as)";
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    49
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    50
text{*
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    51
As a first simple property we prove that looking up a string in the empty
10171
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
    52
trie @{term"Trie None []"} always returns @{term None}. The proof merely
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    53
distinguishes the two cases whether the search string is empty or not:
9458
c613cd06d5cf apply. -> by
nipkow
parents: 8771
diff changeset
    54
*};
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    55
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    56
lemma [simp]: "lookup (Trie None []) as = None";
10171
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
    57
apply(case_tac as, simp_all);
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
    58
done
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    59
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    60
text{*
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    61
Things begin to get interesting with the definition of an update function
12328
7c4ec77a8715 *** empty log message ***
nipkow
parents: 11458
diff changeset
    62
that adds a new (string, value) pair to a trie, overwriting the old value
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    63
associated with that string:
9458
c613cd06d5cf apply. -> by
nipkow
parents: 8771
diff changeset
    64
*};
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    65
10171
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
    66
consts update :: "('a,'v)trie \<Rightarrow> 'a list \<Rightarrow> 'v \<Rightarrow> ('a,'v)trie";
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    67
primrec
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    68
  "update t []     v = Trie (Some v) (alist t)"
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    69
  "update t (a#as) v =
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    70
     (let tt = (case assoc (alist t) a of
10171
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
    71
                  None \<Rightarrow> Trie None [] | Some at \<Rightarrow> at)
10795
9e888d60d3e5 minor edits to Chapters 1-3
paulson
parents: 10171
diff changeset
    72
      in Trie (value t) ((a,update tt as v) # alist t))";
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    73
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    74
text{*\noindent
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    75
The base case is obvious. In the recursive case the subtrie
10171
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
    76
@{term tt} associated with the first letter @{term a} is extracted,
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    77
recursively updated, and then placed in front of the association list.
10171
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
    78
The old subtrie associated with @{term a} is still in the association list
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
    79
but no longer accessible via @{term assoc}. Clearly, there is room here for
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    80
optimizations!
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    81
10171
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
    82
Before we start on any proofs about @{term update} we tell the simplifier to
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
    83
expand all @{text let}s and to split all @{text case}-constructs over
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    84
options:
9458
c613cd06d5cf apply. -> by
nipkow
parents: 8771
diff changeset
    85
*};
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    86
9933
9feb1e0c4cb3 *** empty log message ***
nipkow
parents: 9792
diff changeset
    87
declare Let_def[simp] option.split[split]
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    88
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    89
text{*\noindent
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    90
The reason becomes clear when looking (probably after a failed proof
10171
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
    91
attempt) at the body of @{term update}: it contains both
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
    92
@{text let} and a case distinction over type @{text option}.
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    93
10171
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
    94
Our main goal is to prove the correct interaction of @{term update} and
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
    95
@{term lookup}:
9458
c613cd06d5cf apply. -> by
nipkow
parents: 8771
diff changeset
    96
*};
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    97
10171
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
    98
theorem "\<forall>t v bs. lookup (update t as v) bs =
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
    99
                    (if as=bs then Some v else lookup t bs)";
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   100
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   101
txt{*\noindent
10171
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
   102
Our plan is to induct on @{term as}; hence the remaining variables are
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   103
quantified. From the definitions it is clear that induction on either
11458
09a6c44a48ea numerous stylistic changes and indexing
paulson
parents: 11309
diff changeset
   104
@{term as} or @{term bs} is required. The choice of @{term as} is 
10171
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
   105
guided by the intuition that simplification of @{term lookup} might be easier
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
   106
if @{term update} has already been simplified, which can only happen if
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
   107
@{term as} is instantiated.
11458
09a6c44a48ea numerous stylistic changes and indexing
paulson
parents: 11309
diff changeset
   108
The start of the proof is conventional:
9458
c613cd06d5cf apply. -> by
nipkow
parents: 8771
diff changeset
   109
*};
8771
026f37a86ea7 *** empty log message ***
nipkow
parents: 8745
diff changeset
   110
apply(induct_tac as, auto);
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   111
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   112
txt{*\noindent
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   113
Unfortunately, this time we are left with three intimidating looking subgoals:
9723
a977245dfc8a *** empty log message ***
nipkow
parents: 9689
diff changeset
   114
\begin{isabelle}
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   115
~1.~\dots~{\isasymLongrightarrow}~lookup~\dots~bs~=~lookup~t~bs\isanewline
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   116
~2.~\dots~{\isasymLongrightarrow}~lookup~\dots~bs~=~lookup~t~bs\isanewline
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
   117
~3.~\dots~{\isasymLongrightarrow}~lookup~\dots~bs~=~lookup~t~bs
9723
a977245dfc8a *** empty log message ***
nipkow
parents: 9689
diff changeset
   118
\end{isabelle}
10171
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
   119
Clearly, if we want to make headway we have to instantiate @{term bs} as
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   120
well now. It turns out that instead of induction, case distinction
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   121
suffices:
9458
c613cd06d5cf apply. -> by
nipkow
parents: 8771
diff changeset
   122
*};
10171
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
   123
apply(case_tac[!] bs, auto);
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
   124
done
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   125
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   126
text{*\noindent
11458
09a6c44a48ea numerous stylistic changes and indexing
paulson
parents: 11309
diff changeset
   127
\index{subgoal numbering}%
10171
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
   128
All methods ending in @{text tac} take an optional first argument that
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
   129
specifies the range of subgoals they are applied to, where @{text"[!]"} means
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
   130
all subgoals, i.e.\ @{text"[1-3]"} in our case. Individual subgoal numbers,
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
   131
e.g. @{text"[2]"} are also allowed.
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   132
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   133
This proof may look surprisingly straightforward. However, note that this
9792
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
   134
comes at a cost: the proof script is unreadable because the intermediate
bbefb6ce5cb2 *** empty log message ***
nipkow
parents: 9723
diff changeset
   135
proof states are invisible, and we rely on the (possibly brittle) magic of
10971
6852682eaf16 *** empty log message ***
nipkow
parents: 10795
diff changeset
   136
@{text auto} (@{text simp_all} will not do --- try it) to split the subgoals
10171
59d6633835fa *** empty log message ***
nipkow
parents: 9933
diff changeset
   137
of the induction up in such a way that case distinction on @{term bs} makes
11458
09a6c44a48ea numerous stylistic changes and indexing
paulson
parents: 11309
diff changeset
   138
sense and solves the proof. 
11294
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   139
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   140
\begin{exercise}
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   141
  Modify @{term update} (and its type) such that it allows both insertion and
11303
f0661da2f6ae typo, etc.
paulson
parents: 11294
diff changeset
   142
  deletion of entries with a single function.  Prove the corresponding version 
f0661da2f6ae typo, etc.
paulson
parents: 11294
diff changeset
   143
  of the main theorem above.
f0661da2f6ae typo, etc.
paulson
parents: 11294
diff changeset
   144
  Optimize your function such that it shrinks tries after
f0661da2f6ae typo, etc.
paulson
parents: 11294
diff changeset
   145
  deletion if possible.
11294
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   146
\end{exercise}
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   147
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   148
\begin{exercise}
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   149
  Write an improved version of @{term update} that does not suffer from the
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   150
  space leak (pointed out above) caused by not deleting overwritten entries
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   151
  from the association list. Prove the main theorem for your improved
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   152
  @{term update}.
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   153
\end{exercise}
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   154
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   155
\begin{exercise}
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   156
  Conceptually, each node contains a mapping from letters to optional
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   157
  subtries. Above we have implemented this by means of an association
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   158
  list. Replay the development replacing @{typ "('a * ('a,'v)trie)list"}
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   159
  with @{typ"'a \<Rightarrow> ('a,'v)trie option"}.
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   160
\end{exercise}
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   161
9458
c613cd06d5cf apply. -> by
nipkow
parents: 8771
diff changeset
   162
*};
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   163
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   164
(*<*)
11294
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   165
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   166
(* Exercise 1. Solution by Getrud Bauer *)
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   167
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   168
consts update1 :: "('a, 'v) trie \<Rightarrow> 'a list \<Rightarrow> 'v option \<Rightarrow> ('a, 'v) trie"
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   169
primrec
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   170
  "update1 t []     vo = Trie vo (alist t)"
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   171
  "update1 t (a#as) vo =
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   172
     (let tt = (case assoc (alist t) a of
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   173
                  None \<Rightarrow> Trie None [] 
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   174
                | Some at \<Rightarrow> at)
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   175
      in Trie (value t) ((a, update1 tt as vo) # alist t))"
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   176
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   177
theorem [simp]: "\<forall>t v bs. lookup (update1 t as v) bs =
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   178
                    (if as = bs then v else lookup t bs)";
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   179
apply (induct_tac as, auto);
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   180
apply (case_tac[!] bs, auto);
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   181
done
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   182
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   183
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   184
(* Exercise 2. Solution by Getrud Bauer *)
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   185
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   186
consts overwrite :: "'a \<Rightarrow> 'b \<Rightarrow> ('a * 'b) list \<Rightarrow> ('a * 'b) list"
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   187
primrec
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   188
  "overwrite a v [] = [(a,v)]"
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   189
  "overwrite a v (p#ps) = (if a = fst p then (a,v)#ps else p # overwrite a v ps)"
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   190
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   191
lemma [simp]: "\<forall> a v b. assoc (overwrite a v ps) b = assoc ((a,v)#ps) b"
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   192
apply (induct_tac ps, auto)
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   193
apply (case_tac[!] a)
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   194
done
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   195
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   196
consts update2 :: "('a, 'v) trie \<Rightarrow> 'a list \<Rightarrow> 'v option \<Rightarrow> ('a, 'v) trie";
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   197
primrec
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   198
  "update2 t []     vo = Trie vo (alist t)"
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   199
  "update2 t (a#as) vo =
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   200
     (let tt = (case assoc (alist t) a of 
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   201
                  None \<Rightarrow> Trie None []  
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   202
                | Some at \<Rightarrow> at) 
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   203
      in Trie (value t) (overwrite a (update2 tt as vo) (alist t)))"; 
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   204
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   205
theorem "\<forall>t v bs. lookup (update2 t as vo) bs =
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   206
                    (if as = bs then vo else lookup t bs)";
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   207
apply (induct_tac as, auto);
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   208
apply (case_tac[!] bs, auto);
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   209
done
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   210
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   211
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   212
(* Exercise 3. Solution by Getrud Bauer *)
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   213
datatype ('a,'v) triem = Triem  "'v option" "'a \<Rightarrow> ('a,'v) triem option";
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   214
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   215
consts valuem :: "('a, 'v) triem \<Rightarrow> 'v option"
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   216
primrec "valuem (Triem ov m) = ov";
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   217
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   218
consts mapping :: "('a,'v) triem \<Rightarrow> 'a \<Rightarrow> ('a, 'v) triem option";
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   219
primrec "mapping (Triem ov m) = m";
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   220
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   221
consts lookupm :: "('a,'v) triem \<Rightarrow> 'a list \<Rightarrow> 'v option"
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   222
primrec
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   223
  "lookupm t [] = valuem t"
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   224
  "lookupm t (a#as) = (case mapping t a of
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   225
                        None \<Rightarrow> None
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   226
                      | Some at \<Rightarrow> lookupm at as)";
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   227
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   228
lemma [simp]: "lookupm (Triem None  (\<lambda>c. None)) as = None";
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   229
apply (case_tac as, simp_all);
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   230
done
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   231
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   232
consts updatem :: "('a,'v)triem \<Rightarrow> 'a list \<Rightarrow> 'v \<Rightarrow> ('a,'v)triem"
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   233
primrec
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   234
  "updatem t []     v = Triem (Some v) (mapping t)"
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   235
  "updatem t (a#as) v =
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   236
     (let tt = (case mapping t a of
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   237
                  None \<Rightarrow> Triem None (\<lambda>c. None) 
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   238
                | Some at \<Rightarrow> at)
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   239
      in Triem (valuem t) 
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   240
              (\<lambda>c. if c = a then Some (updatem tt as v) else mapping t c))";
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   241
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   242
theorem "\<forall>t v bs. lookupm (updatem t as v) bs = 
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   243
                    (if as = bs then Some v else lookupm t bs)";
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   244
apply (induct_tac as, auto);
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   245
apply (case_tac[!] bs, auto);
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   246
done
16481a4cc9f3 *** empty log message ***
nipkow
parents: 10978
diff changeset
   247
9458
c613cd06d5cf apply. -> by
nipkow
parents: 8771
diff changeset
   248
end;
8745
13b32661dde4 I wonder which files i forgot.
nipkow
parents:
diff changeset
   249
(*>*)