]> matita.cs.unibo.it Git - helm.git/blob - matita/matita/lib/tutorial/chapter5.ma
Chpater 4 and 5
[helm.git] / matita / matita / lib / tutorial / chapter5.ma
1 (*
2   More Data Types
3 *)
4
5 include "basics/logic.ma".
6
7 (******************************** Option Type *********************************)
8
9 (* Matita may only define total functions. However, not always we may return a 
10 meaningful value: for instance, working on natural numbers, the predecessor of 
11 0 is undefined. In these situations, we may either return a default value 
12 (usually, pred 0 = 0), or decide to return an "option type" as a result. An 
13 Option type is a polymorphic type that represents encapsulation of an optional 
14 value. It consists of either an empty constructor (traditionally called None), 
15 or a constructor encapsulating the original data type A (written Some A): *)
16
17 inductive option (A:Type[0]) : Type[0] ≝
18    None : option A
19  | Some : A → option A.
20  
21 (* The type option A is isomorphic to the disjoint sum between A and unit. The 
22 two bijections are simply defined as
23 follows:
24 \begin{lstlisting}[language=grafite]
25 definition option_to_sum ≝ λA.λx:option A.
26   match x with 
27   [ None ⇒ inl ?? it 
28   | Some a ⇒ inr ?? a ].
29 \end{lstlisting}
30
31 \begin{lstlisting}[language=grafite]
32 definition sum_to_option ≝ λA.λx:unit+A.
33   match x with 
34   [ inl a ⇒ None A
35   | inr a ⇒ Some A a ].
36 \end{lstlisting}
37 The fact that going from the option type to the sum and back again we get the
38 original element follows from a straightforward case analysis:
39 \begin{lstlisting}[language=grafite]
40 lemma option_bij1: ∀A,x. sum_to_option A (option_to_sum A x) = x.
41 #A * // qed. 
42 \end{lstlisting}
43 The other direction is just slightly more complex, since we need to exploit
44 the fact that the unit type contains a single element: we could use lemma ... or
45 proceed by cases on the unit element. 
46 \begin{lstlisting}[language=grafite]
47 lemma option_bij2: ∀A,x. option_to_sum A (sum_to_option A x) = x.
48 #A * // * // qed. 
49 \end{lstlisting}
50 We shall see more examples of functions involving the otion type in the
51 next section.
52
53 \subsection{Lists}
54 The option type, as well as the cartesian product or the sum are simple
55 examples of polymorphic types, that is types that depend in a uniform 
56 and effective way on other types. This form of polymorphism (sometimes
57 called {\em parametric} polymporphism to distinguish it from the 
58 {\em ad hoc} polymorphism
59 typical of object oriented languages) is a major feature of modern 
60 functional programming languages: in many intersting cases,
61 it allows to write {\em generic} functions operating on inputs without 
62 depending on their type. Typical examples can be found on lists.
63 For instance, appending two lists is an operation that is essentially
64 independent from the type $A$ of the elements in the list, and we would like
65 to write a {\em single} append function working parametrically on $A$.
66
67 The first step is to define a type for lists polimorphic over the 
68 type $A$ of its elements:
69 \begin{lstlisting}[language=grafite]
70 inductive list (A:Type[0]) : Type[0] :=
71   | nil: list A
72   | cons: A -> list A -> list A.
73 \end{lstlisting}
74 The deinition should be clear: a list is either empty (\verb+nil+) or
75 is is obtained by concatenating (\verb+cons+) an element of type $A$ 
76 to a given list. In other word, the type of lists is the smallest inductive
77 type generated by the two constructors \verb+nil+ and \verb+cons+.
78
79 The first element of a list is called its {\em head}. If the list
80 is empty the head is undefined: as discussed in the previous section, 
81 we should either return a ``default''
82 element, or decide to return an option type. 
83 We have an additional complication in this
84 case, since the ``default'' element should have type $A$ (as the head),
85 and we know nothing about $A$ (it could even be an empty type!). We
86 have no way to guess a canonical element, and the only
87 possibility (along this approach) is to take it in input. These
88 are the two options:
89 \begin{lstlisting}[language=grafite]
90 definition hd ≝ λA.λl: list A.λd:A.
91   match l with [ nil ⇒ d | cons a _ ⇒ a].
92
93 definition option_hd ≝ 
94   λA.λl:list A. match l with
95   [ nil ⇒ None ?
96   | cons a _ ⇒ Some ? a ].
97 \end{lstlisting}
98 What remains of a list after removing its head is called the {\em tail}
99 of the list. Again, the tail of an empty list is undefined, but in
100 this case the result must be a list, and we have a canonical inhabitant
101 of lists, that is the empty list. So, it is natural to extend the 
102 definition of tail saying that the tail of nil is nil (that is
103 very similar to say that the predecessor of $0$  is $0$):
104 \begin{lstlisting}[language=grafite]
105 definition tail ≝  λA.λl: list A.
106   match l with [ nil ⇒  [] | cons hd tl ⇒  tl].
107 \end{lstlisting}
108
109 Using destruct, it is easy to prove that \verb+cons+ is injective
110 in both arguments.
111 \begin{lstlisting}[language=grafite]
112 lemma cons_injective_l : ∀A.∀a1,a2:A.∀l1,l2.a1::l1 = a2::l2 → a1 = a2.
113 #A #a1 #a2 #l1 #l2 #Heq destruct // qed.
114
115 lemma cons_injective_r : ∀A.∀a1,a2:A.∀l1,l2.a1::l1 = a2::l2 → l1 = l2.
116 #A #a1 #a2 #l1 #l2 #Heq destruct // qed.
117 \end{lstlisting}
118 The append function is defined by recursion over the first list:
119 \begin{lstlisting}[language=grafite]
120 let rec append A (l1: list A) l2 on l1 ≝ 
121   match l1 with
122   [ nil ⇒  l2
123   | cons hd tl ⇒  hd :: append A tl l2 ].
124 \end{lstlisting}
125 We leave to the reader to prove that \verb+append+ is associative, and
126 that \verb+nil+ is a neutral element for it.
127
128 \input{list_notation.tex}
129
130 We conclude this section discussing another important operation
131 over lists, namely the reverse funtion, retrurning
132 a list with the same elements of the original list but in reverse order.
133
134 One could define the revert operation as follows: 
135 \begin{lstlisting}[language=grafite]
136 let rec rev S l1 on l1 ≝
137   match l1 with 
138   [ nil ⇒ nil
139   | cons a tl ⇒ rev A tl @ [a]
140   ].
141 \end{lstlisting}
142 However, this implementation is sligtly inefficient, since it has a 
143 quadratic complexity.
144 A better solution consists in exploiting an accumulator, passing through
145 the following auxilary function:
146 \begin{lstlisting}[language=grafite]
147 let rec rev_append S (l1,l2:list S) on l1 ≝
148   match l1 with 
149   [ nil ⇒ l2
150   | cons a tl ⇒ rev_append S tl (a::l2)
151   ].
152
153 definition reverse ≝λS.λl.rev_append S l [].
154 \end{lstlisting}
155
156 {\bf Exercise} Prove the following results:
157 \begin{lstlisting}[language=grafite]
158 lemma reverse_cons : ∀S,a,l. reverse S (a::l) = (reverse S l)@[a].
159
160 lemma reverse_append: ∀S,l1,l2. 
161   reverse S (l1 @ l2) = (reverse S l2)@(reverse S l1).
162
163 lemma reverse_reverse : ∀S,l. reverse S (reverse S l) = l.
164 \end{lstlisting}
165
166
167 \subsection{List iterators}
168 In general, an iterator for some data type is an object that enables to
169 traverse its structure performing a given computation. 
170 There is a canonical set of iterators over lists deriving from 
171 the programming experience. In this section we shall review a few of
172 them, proving some of their properties.
173
174 A first, famous iterator is the map function, that 
175 applies a function $f$ to each element of a list $[a_1,\dots , a_n]$, 
176 building the list $[f\,a_1; \dots ; f\,a_n]$.
177 \begin{lstlisting}[language=grafite]
178 let rec map (A,B:Type[0]) (f: A → B) (l:list A) on l: list B ≝
179  match l with [ nil ⇒ nil ? | cons x tl ⇒ f x :: (map A B f tl)].
180 \end{lstlisting}
181 The \verb+map+ function distributes over \verb+append+, as can be simply
182 proved by induction over the first list:
183 \begin{lstlisting}[language=grafite]
184 lemma map_append : ∀A,B,f,l1,l2.
185   (map A B f l1) @ (map A B f l2) = map A B f (l1@l2).
186 #A #B #f #l1 elim l1
187   [ #l2 @refl | #h #t #IH #l2 normalize // ] qed.
188 \end{lstlisting}
189 The most important itarator is traditionally called {\em fold}; we
190 shall only consider the so called fold-right variant, 
191 that takes in input a function $f:A\to B \to B$, a list $[a_1; \dots; a_n]$ 
192 of elements of type $A$, a base element $b:B$ and returns
193 the value $f\,a_1\,(f\,a_2\,(\dots (f\,a_n\,b) \dots))$.
194 \begin{lstlisting}[language=grafite]
195 let rec foldr (A,B:Type[0]) (f:A → B → B) (b:B) (l:list A) on l :B ≝  
196  match l with [ nil ⇒ b | cons a l ⇒ f a (foldr A B f b l)].
197 \end{lstlisting}
198 Many other interesting functions can be defined in terms of \verb+foldr+.
199 A first interesting example is the filter function, taking in input
200 a boolean test \verb+p+ and a list $l$ and returning the sublist of all
201 elements of $l$ satisfying the test. 
202 \begin{lstlisting}[language=grafite]
203 definition filter ≝ 
204   λT.λp:T → bool.
205   foldr T (list T) (λx,l0.if p x then x::l0 else l0) (nil T).
206 \end{lstlisting}
207 As another example, we can generalize the map function to an operation
208 taking in input a binary function $f:A\to B \to C$, two lists
209 $[a_1;\dots ;a_n]$ and $[b_1;\dots ;b_m]$ and returning the list 
210 $[f\,a_1\,b_1; \dots ;f\,a_n\,b_1;\dots ;f\,a_1\,b_m; f\,a_n\,b_m]$
211 \begin{lstlisting}[language=grafite]
212 definition compose ≝ λA,B,C.λf:A→B→C.λl1,l2.
213   foldr ?? (λi,acc.(map ?? (f i) l2)@acc) [ ] l1.
214 \end{lstlisting}
215 The folded function $\lambda$\verb+i,acc.(map ?? (f i) l2)@acc+ 
216 takes in input an element $i$ and an accumulator, 
217 and add to the accumulator the values obtained by mapping the 
218 partial instantiation $f\,i$ on the elements of $l_2$. This function 
219 is iterated over
220 all elements of the first list $l_1$, starting with an empty accumulator.
221
222 \subsection{Naive Set Theory}
223 Given a ``universe'' $U$ (an arbitrary type $U:Type$), a naive but
224 practical way to deal with ``sets'' in $U$ is simply to identify
225 them with their characteristic property, that is to as functions
226 of type $U\to \mbox{Prop}$. 
227
228 For instance, the empty set is defined by the False predicate; 
229 a singleton set $\{x\}$ is defined by the property that its elements are
230 equal to $x$.
231
232 \begin{lstlisting}[language=grafite]
233 definition empty_set ≝ λU:Type[0].λu:U.False.
234 definition singleton ≝ λU.λx,u:U.x=u.
235 \end{lstlisting}
236
237 The membership relation is trivial: an element $x$ is in the set
238 (defined by the property) $P$ if and only if it enjoyes the property:
239
240 \begin{lstlisting}[language=grafite]
241 definition member ≝ λU:Type[0].λu:U.P→Prop:U.P u.
242 \end{lstlisting}
243 The operations of union, intersection, complementation and substraction
244 are defined in a straightforward way, in terms of logical operations:
245
246 \begin{lstlisting}[language=grafite]
247 definition union ≝ λU:Type[0].λP,Q:U → Prop.λa.P a ∨ Q a.
248
249 definition intersection ≝ λU:Type[0].λP,Q:U → Prop.λa..P a ∧ Q a.
250
251 definition complement ≝ λU:Type[0].λA:U → Prop.λw.¬ A w.
252
253 definition substraction ≝  λU:Type[0].λA,B:U → Prop.λw.A w ∧ ¬ B w.
254 \end{lstlisting}
255 More interesting are the notions of subset and equality. Given
256 two sets $P$ and $Q$, $P$ is a subset of $Q$ when any element $u$ in
257 $P$ is also in $Q$, that is when $P\,u$ implies $Q\,u$.
258 \begin{lstlisting}[language=grafite]
259 definition subset: ∀A:Type[0].∀P,Q:A→Prop.Prop ≝ λA,P,Q.∀a:A.(P a → Q a).
260 \end{lstlisting}
261 Then, two sets $P$ and $Q$ are equal when $P \subseteq Q$ and 
262 $Q \subseteq P$, or equivalently when for any element $u$, 
263 $P\,u \iff Q\,u$.
264 \begin{lstlisting}[language=grafite]
265 definition eqP ≝ λA:Type.λP,Q:A → Prop.∀a:A.P a ↔ Q a.
266 \end{lstlisting}
267 We shall use the infix notation $\approx$ for the previous notion of 
268 equality.
269 It is important to observe that the \verb+eqP+ is
270 different from Leibniz equality of section \ref{}. As we already
271 observed, Leibniz equality is a pretty syntactical (or intensional)
272 notion, that is a notion concerning the {\em connotation} of an object
273 and not its {\em denotation} (the shape assumed by the object, and
274 not the information it is supposed to convey). Intensionality stands
275 in contrast with {\em extensionality}, referring to principles that 
276 judge objects to be equal if they enjoy {\em a given subset} of external, 
277 observable properties (e.g. the property of having the same 
278 elements). For instance given two sets $A$ and $B$ we can prove that
279 $A\cup B \approx B\cup A$, since they have the same elements, but
280 there is no way to prove $A\cup B = B\cup A$.
281
282 The main practical consequence is that, while we can always exploit
283 a Leibniz equality between two terms $t_1$ and $t_2$ for rewriting
284 one into the other (in fact, this is the {\em essence} of Leibniz 
285 equality), we cannot do the same for an extensional equality (we
286 could only rewrite inside propositions ``compatible'' with our
287 external observation of the objects).  
288
289 \subsection{Sets with decidable equality}
290 We say that a property $P:A\to Prop$ over a datatype $A$ 
291 is {\em decidable} when we have an
292 effective way to assess the validity of $P\,a$ for any 
293 $a:A$. As a consequence
294 of G\"odel incompleteness theorem, not every predicate
295 is decidable: for instance, extensional equality on sets is not decidable,
296 in general.  
297
298 Decidability can be expressed in several possible ways. A convenient
299 one is to state it in terms of the computability of the characterisitc
300 function of the predicate $P$, that is in terms of the existence of a 
301 function $Pb: A \to \mbox{bool}$ such that 
302    \[P\,a \iff Pb\,a = \mbox{true}\]
303 Decidability is an important issue, and since equality is an essential 
304 predicate, it is always interesting to try to understand when a given 
305 notion of equality is decidable or not. 
306
307 In particular, Leibniz equality on inductively generated datastructures
308 is often decidable, since we can simply write a decision algorithm by
309 structural induction on the terms. For instance we can define
310 characteristic functions for booleans and natural numbers in the following
311 way:
312 \begin{lstlisting}[language=grafite]
313 definition beqb ≝ λb1,b2.
314   match b1 with [ true ⇒ b2 | false ⇒ notb b2].
315
316 let rec neqb n m ≝ 
317 match n with 
318   [ O ⇒ match m with [ O ⇒ true | S q ⇒ false] 
319   | S p ⇒ match m with [ O ⇒ false | S q ⇒ neqb p q]
320   ].
321 \end{lstlisting}
322 It is so important to know if Leibniz equality for a given type is decidable 
323 that turns out to be convenient to pack this information into a single 
324 algebraic datastructure, called \verb+DeqSet+:
325 \begin{lstlisting}[language=grafite]
326 record DeqSet : Type[1] ≝ 
327  { carr :> Type[0];
328    eqb: carr → carr → bool;
329    eqb_true: ∀x,y. (eqb x y = true) ↔ (x = y)}.
330
331 notation "a == b" non associative with precedence 45 for @{ 'eqb $a $b }.
332 interpretation "eqb" 'eqb a b = (eqb ? a b).
333 \end{lstlisting}
334 A \verb+DeqSet+ is simply a record composed by a carrier type \verb+carr+,
335 a boolean function \verb+eqb: carr+$\to$\verb+carr+$\to$\verb+carr+ representing 
336 the decision algorithm, and a {\em proof} \verb+eqb_true+ that the decision algorithm
337 is correct. The \verb+:>+ symbol declares \verb+carr+ as a {\em coercion} from a DeqSet to its 
338 carrier type. We use the infix notation ``=='' for the decidable
339 equality \verb+eqb+ of the carrier.
340
341 Suppose we proved the following facts (do it as an exercise)
342 \begin{lstlisting}[language=grafite]
343 lemma beqb_true_to_eq: ∀b1,b2. beqb b1 b2 = true ↔ b1 = b2.
344 lemma neqb_true_to_eq: ∀n,m:nat. eqb n m = true → n = m.
345 \end{lstlisting}
346 Then, we can build the following records:
347 \begin{lstlisting}[language=grafite]
348 definition DeqBool ≝ mk_DeqSet bool beqb beqb_true_to_eq.
349 definition DeqNat ≝ mk_DeqSet nat eqb eqbnat_true.
350 \end{lstlisting}
351 Note that, since we declare a coercion from the \verb+DeqSet+ to its
352 carrier, the expression \verb+0:DeqNat+ is well typed, and it is understood 
353 by the system as \verb+0:carr DeqNat+ (that is, coercions are automatically
354 insterted by the system, if required).
355
356 %It is convenient to have a simple way to {\em reflect} \cite{ssreflect}
357 %a proof of
358 %$(eqb\;x\;y = true)$ into a proof of $(x = y)$; we use the two operators
359 %$\mathit{\\P}$ and $\mathit{\\b}$ to this aim.
360
361 \subsection{Unification hints}
362 Suppose now to write an expression of the following kind:
363 \[b == \mbox{false}\]
364 that, after removing the notation, is equivalent to 
365 \[eqb\;?\;b\;\mbox{false}\]
366 The system knows that $\mbox{false}$ is a boolean, so in order to 
367 accept the expression, he should {\em figure out} some \verb+DeqSet+ 
368 having \verb+bool+
369 as carrier. This is not a trivial operation: Matita should either try
370 to synthetize it (that is a complex operation known as {\em narrowing}) 
371 or look into its database of results for a possible solution. 
372
373 In this situations, we may suggest the intended solution to Matita using
374 the mechanism of unification hints \cite{hints}. The concrete syntax
375 of unification hints is a bit involved: we strongly recommend the user
376 to include the file \verb+hints_declaration.ma+ that allows you
377 to write thing in a more convenient and readable way.
378 \begin{lstlisting}[language=grafite]
379 include ``hints_declaration.ma''.
380 \end{lstlisting}
381 For instance, the following declaration tells Matita that a solution
382 of the equation \verb+bool = carr X+ is $X = DeqBool$.
383 \begin{lstlisting}[language=grafite]
384 unification hint  0 ≔ ; 
385     X ≟ DeqBool
386 (* ---------------------------------------- *) ⊢ 
387     bool ≡ carr X.
388 \end{lstlisting}
389 Using the previous notation (we suggest the reader to cut and paste it
390 from previous hints) the hint is expressed as an inference rule.
391 The conclusion of the rule is the unification problem that we intend to solve, 
392 containing one or more variables $X_1,\dots X_b$. The premises of
393 the rule are the solutions we are suggesting to Matita. In general,
394 unification hints should only be used when there exists just one
395 ``intended'' (canonical) solution for the given equation. 
396 When you declare a unification hint, Matita verifies it correctness by
397 instantiating the unification problem with the hinted solution, 
398 and checking the convertibility between the two sides of the equation.
399 \begin{lstlisting}[language=grafite]       
400 example exhint: ∀b:bool. (b == false) = true → b = false. 
401 #b #H @(\P H).
402 qed.
403 \end{lstlisting}
404 In a similar way, 
405
406 \begin{lstlisting}[language=grafite]   
407 unification hint  0 ≔ b1,b2:bool; 
408     X ≟ mk_DeqSet bool beqb beqb_true
409 (* ---------------------------------------- *) ⊢ 
410     beqb b1 b2 ≡ eqb X b1 b2.
411 \end{lstlisting}
412
413
414 \subsection{Prop vs. bool}
415 It is probably time to make a discussion about \verb+Prop+ and \verb+bool+, and
416 their different roles in a the Calculus of Inductive Constructions. 
417
418 Inhabitants of the sort \verb+Prop+ are logical propositions. In turn, logical
419 propositions \verb+P:Prop+ can be inhabitated by their proofs $H:P$. Since, in
420 general, the validity of a property $P$is not decidable, the role of the
421 proof is to provide a witness of the correctness of $P$ that the system can 
422 automatically check.
423
424 On the other hand, bool is just an inductive datatype with two constructors true
425 and false: these are terms, not types, and cannot be inhabited.
426 Logical connectives on bool are computable functions, defined by their
427 truth tables, using case analysis.
428   
429   Prop and bool are, in a sense, complementary: the former is more suited for 
430 abstract logical reasoning, 
431 while the latter allows, in some situations, for brute-force evaluation. 
432 Suppose for instance that we wish to prove that the $2 \le 3!$. Starting
433 from the definition of the factorial function and properties of the less
434 or equal relation, the previous proof could take several steps. Suppose
435 however we proved the decidability of $\le$, that is the existence of
436 a boolean function $\mbox{leb}$ reflecting $\le$ in the sense that
437 \[n \le m \iff \mbox{leb}\,n,m = \mbox{true}\]
438 Then, we could reduce the verification of $2 \le 3!$ to that of 
439 of $\mbox{leb}\,2,3! = \mbox{true}$ that just requires a mere computation!
440
441 \subsection{Finite Sets}
442 A finite set is a record consisting of a DeqSet $A$, 
443 a list of elements of type A enumerating all the elements of the set,
444 and the proofs that the enumeration does not contain repetitions 
445 and is complete (\verb+memb+ is the membership operation on 
446 lists, defined in the obvious way, and the question mark is an {\em
447 implicit parameter} automatically filled in by the system). 
448 \begin{lstlisting}[language=grafite]
449 record FinSet : ≝ 
450 { FinSetcarr:> DeqSet;
451   enum: list FinSetcarr;
452   enum_unique: uniqueb FinSetcarr enum = true;
453   enum_complete : ∀x:FinSetcarr. memb ? x enum = true}.
454 \end{lstlisting}
455 The library provides many operations for building new \verb+FinSet+s by 
456 composing
457 existing ones: for example, 
458 if \verb+A+ and \verb+B+ have type \verb+FinSet+, then 
459 also \verb+option A+, \verb+A+$\times$\verb+B+, 
460 \verb+A+$\oplus$\verb+B+ are finite sets. In all these cases, unification 
461 hints are used to suggest the {\em intended} finite set structure 
462 associated with them, that makes their use quite transparent to the user.
463
464 A particularly intersting case is that of the arrow type \verb+A+$\to$\verb+B+. 
465 We may define the graph of \verb+f:A+$\to$\verb+B+, as the 
466 set (sigma type) of all pairs $\langle a,b \rangle$ such that
467 $f (a) = b$. 
468 \begin{lstlisting}[language=grafite]
469 definition graph_of ≝ λA,B.λf:A→B. Σp:A×B.f (\fst p) = \snd p.
470 \end{lstlisting}
471 In case the equality is decidable, we may effectively
472 enumerate all elements of the graph by simply filtering from
473 pairs in \verb+A+$\times$\verb+B+ those satisfying the 
474 test $\lambda$\verb+p.f (\fst p) == \snd p)+:
475
476 \begin{lstlisting}[language=grafite]
477 definition graph_enum ≝ λA,B:FinSet.λf:A→B. 
478   filter ? (λp.f (\fst p) == \snd p) (enum (FinProd A B)).
479 \end{lstlisting}
480 The proofs that this enumeration does not contain repetitions and
481 is complete are straightforward.
482
483 \subsection{Vectors}
484 A vector of length $n$ of elements of type $A$ 
485 is simply defined in Matita as a record composed 
486 by a list of elements of type $A$, plus a proof that the
487 list has the expected length. Vectors are a paradigmatic example 
488 of {\em dependent} type, that is of a type whose definition depends on
489 a term.
490 \begin{lstlisting}[language=grafite]
491 record Vector (A:Type) (n:nat): Type ≝ 
492 { vec :> list A;
493   len: length ? vec = n }.
494 \end{lstlisting}
495 Given a list $l$ we may trivially turn it into a vector of length $|l|$; 
496 we just need to prove that $|l|=|l|$ that follows from the reflexivity
497 of equality.
498 \begin{lstlisting}[language=grafite]
499 lemma Vector_of_list ≝ λA,l.mk_Vector A (|l|) l (refl ??).
500 \end{lstlisting}
501
502 Most functions operating on lists can be naturally extended to 
503 vectors: interesting cases are \verb+vec_append+, concatenating vectors, 
504 and \verb+vec_map+, mapping a function $f$ on all elements of the input
505 vector and returning a vector of the same dimension of the input one.
506
507 Since a vector is automatically coerced, if needed, to the list of
508 its elements, we may simply use typical functions over lists (such as
509 \verb+nth+) to extract/filter specific components.
510
511 The function \verb+change_vec A n v a i+ replaces the content of
512 the vector $v$ at position $i$ with the value $a$. 
513
514 The most frequent operation on vectors for the purposes or our work
515 is their comparison. In this case, we have essentially two possible 
516 approaches: we may proceed component-wise, using the following lemma
517 \begin{lstlisting}[language=grafite]
518 lemma eq_vec: ∀A,n.∀v1,v2:Vector A n.∀d. 
519   (∀i. i < n → nth i A v1 d = nth i A v2 d) → v1 = v2.
520 \end{lstlisting}
521 or alternatively we may manipulate vectors exploiting the commutation
522 or idempotency of \verb+change_vec+ and its interplay with 
523 other operations.