2 \ 5h1
\ 6Matita Interactive Tutorial
\ 5/h1
\ 6
3 \ 5b
\ 6The goat, the wolf and the cabbage
\ 5/b
\ 6
4 A farmer need to transfer a goat, a wolf and a cabbage across a river, but there
5 is only one place available on his boat. Furthermore, the goat will eat the
6 cabbage if they are left alone on the same bank, and similarly the wolf will eat
7 the goat. The problem consists in bringing all three items safely across the
10 Our first data type defines the two banks of the river, which will be named east
11 and west. It is a simple example of enumerated type, defined by explicitly
12 declaring all its elements. The type itself is called "bank".
13 Before giving its definition we "include" the file "logic.ma" that contains a
14 few preliminary notions not worth discussing for the moment.
17 include "basics/logic.ma".
19 inductive bank: Type[0] ≝
23 (* We can now define a simple function computing, for each bank of the river, the
26 definition opposite ≝ λs.
32 (* The goal window. Computation. *)
33 lemma east_to_west : opposite east = west.
37 (* the computation step is not necessary *)
38 lemma west_to_east : opposite west = east.
41 (* A slightly more complex problem consists in proving that opposite is idempotent *)
42 lemma idempotent_opposite : ∀x. opposite (opposite x) = x.
48 \ 5h2 class="section"
\ 6Predicates
\ 5/h2
\ 6
49 Instead of working with functions, it is sometimes convenient to work with
50 predicates. For instance, instead of defining a function computing the opposite
51 bank, we could declare a predicate stating when two banks are opposite to each
52 other. Only two cases are possible, leading naturally to the following
56 inductive opp : bank → bank → Prop ≝
57 | east_west : opp east west
58 | west_east : opp west east.
60 (* In precisely the same way as "bank" is the smallest type containing east and
61 west, opp is the smallest predicate containing the two sub-cases east_west and
62 weast_east. If you have some familiarity with Prolog, you may look at opp as the
63 predicate defined by the two clauses - in this case, the two facts - ast_west and
66 Between opp and opposite we have the following relation:
67 opp a b iff a = opposite b
68 Let us prove it, starting from the left to right implication, first *)
70 lemma opp_to_opposite: ∀a,b. opp a b → a = opposite b.
75 \ 5h2 class="section"
\ 6Rewriting
\ 5/h2
\ 6
76 Let us come to the opposite direction. *)
78 lemma opposite_to_opp: ∀a,b. a = opposite b → opp a b.
84 \ 5h2 class="section"
\ 6Records
\ 5/h2
\ 6
85 It is time to proceed with our formalization of the farmer's problem.
86 A state of the system is defined by the position of four items: the goat, the
87 wolf, the cabbage, and the boat. The simplest way to declare such a data type
91 record state : Type[0] ≝
97 (* When you define a record named foo, the system automatically defines a record
98 constructor named mk_foo. To construct a new record you pass as arguments to
99 mk_foo the values of the record fields *)
101 definition start ≝ mk_state east east east east.
102 definition end ≝ mk_state west west west west.
104 (* We must now define the possible moves. A natural way to do it is in the form
105 of a relation (a binary predicate) over states.
108 ----------------------- (move_goat)
109 (g,w,c,g) ↦ (g1,w,c,g1)
112 ----------------------- (move_wolf)
113 (g,w,c,w) ↦ (g,w1,c,w1)
116 ----------------------- (move_cabbage)
117 (g,w,c,c) ↦ (g,w,c1,c1)
120 ---------------------- (move_boat)
121 (g,w,c,b) ↦ (g,w,c,b1)
125 inductive move : state → state → Prop ≝
126 | move_goat: ∀g,g1,w,c. opp g g1 → move (mk_state g w c g) (mk_state g1 w c g1)
127 (* We can move the goat from a bank g to the opposite bank g1 if and only if the
128 boat is on the same bank g of the goat and we move the boat along with it. *)
129 | move_wolf: ∀g,w,w1,c. opp w w1 → move (mk_state g w c w) (mk_state g w1 c w1)
130 | move_cabbage: ∀g,w,c,c1.opp c c1 → move (mk_state g w c c) (mk_state g w c1 c1)
131 | move_boat: ∀g,w,c,b,b1. opp b b1 → move (mk_state g w c b) (mk_state g w c b1).
133 (* A state is safe if either the goat is on the same bank of the boat, or both
134 the wolf and the cabbage are on the opposite bank of the goat. *)
136 inductive safe_state : state → Prop ≝
137 | with_boat : ∀g,w,c.safe_state (mk_state g w c g)
138 | opposite_side : ∀g,g1,b.opp g g1 → safe_state (mk_state g g1 g1 b).
140 (* Finally, a state y is reachable from x if either there is a single move
141 leading from x to y, or there is a safe state z such that z is reachable from x
142 and there is a move leading from z to y *)
144 inductive reachable : state → state → Prop ≝
145 | one : ∀x,y.move x y → reachable x y
146 | more : ∀x,z,y.
\ 5span style="text-decoration: underline;"
\ 6\ 5/span
\ 6reachable x z → safe_state z →
\ 5span style="text-decoration: underline;"
\ 6\ 5/span
\ 6move z y → reachable x y.
149 \ 5h2 class="section"
\ 6Automation
\ 5/h2
\ 6
150 Remarkably, Matita is now able to solve the problem by itself, provided
151 you allow automation to exploit more resources. The command /n/ is similar to
152 //, where n is a measure of this complexity: in particular it is a bound to
153 the depth of the expected proof tree (more precisely, to the number of nested
154 applicative nodes). In this case, there is a solution in six moves, and we
155 need a few more applications to handle reachability, and side conditions.
156 The magic number to let automation work is, in this case, 9. *)
158 lemma problem: reachable start end.
162 \ 5h2 class="section"
\ 6A complex interactive proof
\ 5/h2
\ 6
163 Let us now try to derive the proof in a more interactive way. Of course, we
164 expect to need several moves to transfer all items from a bank to the other, so
165 we should start our proof by applying "more". Matita syntax for invoking the
166 application of a property named foo is to write "@foo". In general, the philosophy
167 of Matita is to describe each proof of a property P as a structured collection of
168 objects involved in the proof, prefixed by simple modalities (#,<,@,...) explaining
169 the way it is actually used (e.g. for introduction, rewriting, in an applicative
176 lemma problem1: reachable start end.
179 - multiple conjectures
182 [ @(mk_state east west west east)
186 (* implicit arguments *)
187 @(more ? (mk_state east west west west))
190 (* vectors of implicit arguments *)
191 @(more … (move_wolf … ))
196 (* Alternatively, we can directly instantiate the bank into the move. Let
197 us complete the proof in this, very readable way. *)
198 @(more … (move_goat west … )) /2/
199 @(more … (move_cabbage ?? east … )) /2/
200 @(more … (move_boat ??? west … )) /2/