]> matita.cs.unibo.it Git - helm.git/commitdiff
commit by user andrea
authormatitaweb <claudio.sacerdoticoen@unibo.it>
Mon, 3 Oct 2011 08:15:18 +0000 (08:15 +0000)
committermatitaweb <claudio.sacerdoticoen@unibo.it>
Mon, 3 Oct 2011 08:15:18 +0000 (08:15 +0000)
weblib/tutorial/chapter1.ma

index c2523f38c803f8472106b853b6d6e4e1d4d0d565..69466662ae9a1869ec177f508f6747c0c0540bf9 100644 (file)
@@ -1,23 +1,39 @@
-
 (*
-In a system like Matita's very few things are built-in: not even booleans or 
-logical connectives. The main philosophy od the system is to let you define your 
-own data-types and functions using a powerful computational mechanism based on 
-the declaration of inductive types. 
-
-Let us start this tutorial with a simple example based on the following well known
-problem.
-
-\ 5h2 class="section"\ 6The goat, the wolf and the cabbage\ 5/h2\ 6\ 5div class="paragraph"\ 6\ 5/div\ 6A farmer need to tranfer a goat, a wolf and a cabbage across a river, but there is
-only one place available on his boat. Furthermore, the goat will eat the cabbage if 
-they are left alone on the same bank, and similarly the wolf will eat the goat. 
-The problem consists in bringing all three item safely across the river. 
-
-Our first data type defines the two banks of the river, which we will call east and 
-west. It is a simple example of enumerated type, defined by explicitly declaring all 
-its elements. The type itself is called "bank".
-Before giving its definition we "include" the file "logic.ma" that contains a a few 
-preliminary notions not worth discussing here.
+This is an interactive tutorial. To let you interact on line with the system, 
+you must first of all register yourself.
+
+Before starting, let us briefly explain the meaning of the menu buttons. 
+With the Advance and Retract buttons you respectively perform and undo single 
+computational steps. Each step consists in reading a user command, and processing
+it. The part of the user input file (called script) already executed by the 
+system will be colored, and will not be editable any more. The advance bottom 
+will also automatically advance the focus of the window, but you can inspect the 
+whole file using the scroll bars, as usual. Comments are skipped.
+Try to advance and retract a few steps, to get the feeling of the system. You can 
+also come back here by using the top button, that takes you at the beginning of 
+a file. The play button is meant to process the script up to a position 
+previously selected by the user; the bottom button execute the whole script. 
+That's it: we are\ 5span style="font-family: Verdana,sans-serif;"\ 6 \ 5/span\ 6now ready to start.
+
+The first thing to say is that in a system like Matita's very few things are 
+built-in: not even booleans or logical connectives. The main philosophy of the 
+system is to let you define your own data-types and functions using a powerful 
+computational mechanism based on the declaration of inductive types. 
+
+Let us start this tutorial with a simple example based on the following well 
+known problem.
+
+\ 5h2 class="section"\ 6The goat, the wolf and the cabbage\ 5/h2\ 6\ 5div class="paragraph"\ 6\ 5/div\ 6A farmer need to transfer a goat, a wolf and a cabbage across a river, but there
+is only one place available on his boat. Furthermore, the goat will eat the 
+cabbage if they are left alone on the same bank, and similarly the wolf will eat
+the goat. The problem consists in bringing all three items safely across the 
+river. 
+
+Our first data type defines the two banks of the river, which will be named east
+and west. It is a simple example of enumerated type, defined by explicitly 
+declaring all its elements. The type itself is called "bank".
+Before giving its definition we "include" the file "logic.ma" that contains a 
+few preliminary notions not worth discussing for the moment.
 *)
 
 include "basics/logic.ma".
@@ -26,8 +42,8 @@ inductive bank: Type[0] ≝
 | east : bank 
 | west : bank.
 
-(* We can now define a simple function computing, for each bank of the river,
-the opposite one. *)
+(* We can now define a simple function computing, for each bank of the river, the
+opposite one. *)
 
 definition opposite ≝ λs.
 match s with
@@ -69,170 +85,226 @@ You may use the retract bottom to undo the step, if you wish.
 The new goal west = west is trivial: it is just a consequence of reflexivity.
 Such trivial steps can be just closed in Matita by typing a double slash. 
 We complete the proof by the qed command, that instructs the system to store the
-lemma performing some bookkeeping operations. 
+lemma performing some book-keeping operations. 
 *)
 
 // qed.
 
-lemma west_to_east : change_side west = east.
+(* In exactly the same way, we can prove that the opposite side of west is east.
+In this case, we avoid the unnecessary simplification step: // will take care of 
+it. *) 
+
+lemma west_to_east : \ 5a href="cic:/matita/tutorial/chapter1/opposite.def(1)"\ 6opposite\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,2,0)"\ 6west\ 5/a\ 6 \ 5a title="leibnitz's equality" href="cic:/fakeuri.def(1)"\ 6=\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,1,0)"\ 6east\ 5/a\ 6.
 // qed.
 
-lemma change_twice : ∀x. change_side (change_side x) = x.
-* //
-qed.
+(* A slightly more complex problem consists in proving that opposite is 
+idempotent *)
 
-inductive item: Type[0] ≝
-| goat : item
-| wolf : item
-| cabbage: item
-| boat : item.
+lemma idempotent_opposite : ∀x. \ 5a href="cic:/matita/tutorial/chapter1/opposite.def(1)"\ 6opposite\ 5/a\ 6 (\ 5a href="cic:/matita/tutorial/chapter1/opposite.def(1)"\ 6opposite\ 5/a\ 6 x) \ 5a title="leibnitz's equality" href="cic:/fakeuri.def(1)"\ 6=\ 5/a\ 6 x.
 
-(* definition state ≝ item → side. *)
+(* we start the proof moving x from the conclusion into the context, that is a 
+(backward) introduction step. Matita syntax for an introduction step is simply 
+the sharp character followed by the name of the item to be moved into the 
+context. This also allows us to rename the item, if needed: for instance if we 
+wish to rename x into b (since it is a bank), we just type #b. *)
 
-record state : Type[0] ≝
-  {goat_pos : side;
-   wolf_pos : side;
-   cabbage_pos: side;
-   boat_pos : side}.
-
-definition state_of_item ≝ λs,i.
-match i with
-[ goat ⇒  goat_pos s
-| wolf ⇒  wolf_pos s
-| cabbage ⇒  cabbage_pos s
-| boat ⇒  boat_pos s].
+#b
 
-(*
-definition is_movable ≝ λs,i.
-  state_of_item s i = state_of_item s boat.
-record movable_item (s:state) : Type[0] ≝
-  {elem : item;
-   mov : is_movable s elem}. *)
-definition start :state ≝ 
-  mk_state east east east east.
-
-(* slow
-inductive move : state → state → Type[0] ≝
-| move_goat: ∀g,w,c.
-  move (mk_state (change_side g) w c (change_side g)) (mk_state g w c g) 
-| move_wolf: ∀g,w,c.
-  move (mk_state g (change_side w) c (change_side w)) (mk_state g w c w)
-| move_cabbage: ∀g,w,c.
-  move (mk_state g w (change_side c) (change_side c)) (mk_state g w c c)
-| move_boat: ∀g,w,c,b.
-  move (mk_state g w c (change_side b)) (mk_state g w c b).
+(* See the effect of the execution in the goal window on the right: b has been 
+added to the context (replacing x in the conclusion); moreover its implicit type 
+"bank" has been made explicit. 
+
+But how are we supposed to proceed, now? Simplification cannot help us, since b
+is a variable: just try to call normalize and you will see that it has no effect.
+The point is that we must proceed by cases according to the possible values of b,
+namely east and west. To this aim, you must invoke the cases command, followed by
+the name of the hypothesis (more generally, an arbitrary expression) that must be
+the object of the case analysis (in our case, b).
 *)
 
-(*  this is working well *)
-inductive move : state → state → Type[0] ≝
-| move_goat: ∀g,w,c.
-  move (mk_state g w c g) (mk_state (change_side g) w c (change_side g)) 
-| move_wolf: ∀g,w,c.
-  move (mk_state g w c w) (mk_state g (change_side w) c (change_side w))
-| move_cabbage: ∀g,w,c.
-  move (mk_state g w c c) (mk_state g w (change_side c) (change_side c))
-| move_boat: ∀g,w,c,b.
-  move (mk_state g w c b) (mk_state g w c (change_side b)).
+cases b
 
-(* this is working 
-inductive move : state → state → Type[0] ≝
-| move_goat: ∀g,g1,w,c. change_side g = g1 → 
-  move (mk_state g w c g) (mk_state g1 w c g1) 
-| move_wolf: ∀g,w,w1,c. change_side w = w1 → 
-  move (mk_state g w c w) (mk_state g w1 c w1)
-| move_cabbage: ∀g,w,c,c1. change_side c = c1 → 
-  move (mk_state g w c c) (mk_state g w c1 c1)
-| move_boat: ∀g,w,c,b,b1. change_side b = b1 →
-  move (mk_state g w c b) (mk_state g w c b1) 
-.*)
+(* Executing the previous command has the effect of opening two subgoals, 
+corresponding to the two cases b=east and b=west: you may switch from one to the 
+other by using the hyperlinks over the top of the goal window. 
+Both goals can be closed by trivial computations, so we may use // as usual.
+If we had to treat each subgoal in a different way, we should focus on each of 
+them in turn, in a way that will be described at the end of this section.
+*)
 
-(*
-inductive move : state →state → Type[0] ≝
-| move_goat: ∀s.∀h:is_movable s goat. move s (mk_state (change_side (goat_pos s)) (wolf_pos s) 
-  (cabbage_pos s) (change_side (boat_pos s)))
-| move_wolf: ∀s.∀h:is_movable s wolf. move s (mk_state (goat_pos s) (change_side (wolf_pos s))
-  (cabbage_pos s) (change_side (boat_pos s)))
-| move_cabbage: ∀s.∀h:is_movable s cabbage. move s (mk_state (goat_pos s) (wolf_pos s) 
-  (change_side (cabbage_pos s)) (change_side (boat_pos s)))
-| move_boat: ∀s.move s (mk_state (goat_pos s) (wolf_pos s) 
-  (cabbage_pos s) (change_side (boat_pos s))).
+// qed.
+
+(* Instead of working with functions, it is sometimes convenient to work with
+predicates. For instance, instead of defining a function computing the opposite 
+bank, we could declare a predicate stating when two banks are opposite to each 
+other. Only two cases are possible, leading naturally two the following 
+definition:
 *)
 
-(*
-definition legal_state ≝ λs.
-  goat_pos s = boat_pos s ∨  
-  (goat_pos s = change_side (cabbage_pos s) ∧ 
-   goat_pos s = change_side (wolf_pos s)). *)
-
-inductive legal_state : state → Prop ≝
-| with_boat : ∀g,w,c.legal_state (mk_state g w c g)
-| opposite_side : ∀g,b. 
-    legal_state (mk_state g (change_side g) (change_side g) b).
-  
-inductive reachable : state → state → Prop ≝
-| one : ∀s1,s2.move s1 s2 → reachable s1 s2
-| more : ∀s1,s2,s3. reachable s1 s2 → legal_state s2 → move s2 s3 →
-  reachable s1 s3. 
-
-definition end ≝ mk_state west west west west.
-definition second ≝ mk_state west east east west.
-definition third ≝ mk_state west east east east.
-definition fourth ≝ mk_state west west east west.
-definition fifth ≝ mk_state east west east east.
-definition sixth ≝ mk_state east west west west.
-definition seventh ≝ mk_state east west west east.
-
-lemma problem: reachable start end.
-normalize /8/ qed. 
-
-lemma problem: reachable start end.
+inductive opp : \ 5a href="cic:/matita/tutorial/chapter1/bank.ind(1,0,0)"\ 6bank\ 5/a\ 6 → \ 5a href="cic:/matita/tutorial/chapter1/bank.ind(1,0,0)"\ 6bank\ 5/a\ 6 → Prop ≝ 
+| east_west : opp \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,1,0)"\ 6east\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,2,0)"\ 6west\ 5/a\ 6
+| west_east : opp \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,2,0)"\ 6west\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,1,0)"\ 6east\ 5/a\ 6.
+
+(* In precisely the same way as "bank" is the smallest type containing east and
+west, opp is the smallest predicate containing the two sub-cases east_west and
+weast_east. If you have some familiarity with Prolog, you may look at opp as the
+predicate definined by the two clauses - in this case, the two facts -
+(opp east west) and (opp west east). 
+At the end of this section we shall prove that forall a and b, 
+                  (opp a b) iff a = opposite b.
+For the moment, it is time to proceed with our formalization of the farmer's 
+problem. 
+A state of the system is defined by the position of four item: the goat, the 
+wolf, the cabbage, and the boat. The simplest way to declare such a data type
+is to use a record.
+*)
+
+record state : Type[0] ≝
+  {goat_pos : \ 5a href="cic:/matita/tutorial/chapter1/bank.ind(1,0,0)"\ 6bank\ 5/a\ 6;
+   wolf_pos : \ 5a href="cic:/matita/tutorial/chapter1/bank.ind(1,0,0)"\ 6bank\ 5/a\ 6;
+   cabbage_pos: \ 5a href="cic:/matita/tutorial/chapter1/bank.ind(1,0,0)"\ 6bank\ 5/a\ 6;
+   boat_pos : \ 5a href="cic:/matita/tutorial/chapter1/bank.ind(1,0,0)"\ 6bank\ 5/a\ 6}.
+
+(* When you define a record named foo, the system automatically defines a record 
+constructor named mk_foo. To construct a new record you pass as arguments to 
+mk_foo the values of the record fields *)
+
+definition start ≝ \ 5a href="cic:/matita/tutorial/chapter1/state.con(0,1,0)"\ 6mk_state\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,1,0)"\ 6east\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,1,0)"\ 6east\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,1,0)"\ 6east\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,1,0)"\ 6east\ 5/a\ 6.
+definition end ≝ \ 5a href="cic:/matita/tutorial/chapter1/state.con(0,1,0)"\ 6mk_state\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,2,0)"\ 6west\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,2,0)"\ 6west\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,2,0)"\ 6west\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,2,0)"\ 6west\ 5/a\ 6.
+
+(* We must now define the possible moves. A natural way to do it is in the form 
+of a relation (a binary predicate) over states. *)
+
+inductive move : \ 5a href="cic:/matita/tutorial/chapter1/state.ind(1,0,0)"\ 6state\ 5/a\ 6 → \ 5a href="cic:/matita/tutorial/chapter1/state.ind(1,0,0)"\ 6state\ 5/a\ 6 → Prop ≝
+| move_goat: ∀g,g1,w,c. \ 5a href="cic:/matita/tutorial/chapter1/opp.ind(1,0,0)"\ 6opp\ 5/a\ 6 g g1 → move (\ 5a href="cic:/matita/tutorial/chapter1/state.con(0,1,0)"\ 6mk_state\ 5/a\ 6 g w c g) (\ 5a href="cic:/matita/tutorial/chapter1/state.con(0,1,0)"\ 6mk_state\ 5/a\ 6 g1 w c g1) 
+| move_wolf: ∀g,w,w1,c. \ 5a href="cic:/matita/tutorial/chapter1/opp.ind(1,0,0)"\ 6opp\ 5/a\ 6 w w1 → move (\ 5a href="cic:/matita/tutorial/chapter1/state.con(0,1,0)"\ 6mk_state\ 5/a\ 6 g w c w) (\ 5a href="cic:/matita/tutorial/chapter1/state.con(0,1,0)"\ 6mk_state\ 5/a\ 6 g w1 c w1)
+| move_cabbage: ∀g,w,c,c1.\ 5a href="cic:/matita/tutorial/chapter1/opp.ind(1,0,0)"\ 6opp\ 5/a\ 6 c c1 → move (\ 5a href="cic:/matita/tutorial/chapter1/state.con(0,1,0)"\ 6mk_state\ 5/a\ 6 g w c c) (\ 5a href="cic:/matita/tutorial/chapter1/state.con(0,1,0)"\ 6mk_state\ 5/a\ 6 g w c1 c1)
+| move_boat: ∀g,w,c,b,b1. \ 5a href="cic:/matita/tutorial/chapter1/opp.ind(1,0,0)"\ 6opp\ 5/a\ 6 b b1 → move (\ 5a href="cic:/matita/tutorial/chapter1/state.con(0,1,0)"\ 6mk_state\ 5/a\ 6 g w c b) (\ 5a href="cic:/matita/tutorial/chapter1/state.con(0,1,0)"\ 6mk_state\ 5/a\ 6 g w c b1).
+
+(* A state is safe if either the goat is on the same bank of the boat, or both 
+the wolf and the cabbage are on the opposite bank of the goat. *)
+
+inductive safe_state : \ 5a href="cic:/matita/tutorial/chapter1/state.ind(1,0,0)"\ 6state\ 5/a\ 6 → Prop ≝
+| with_boat : ∀g,w,c.safe_state (\ 5a href="cic:/matita/tutorial/chapter1/state.con(0,1,0)"\ 6mk_state\ 5/a\ 6 g w c g)
+| opposite_side : ∀g,g1,b.\ 5a href="cic:/matita/tutorial/chapter1/opp.ind(1,0,0)"\ 6opp\ 5/a\ 6 g g1 → safe_state (\ 5a href="cic:/matita/tutorial/chapter1/state.con(0,1,0)"\ 6mk_state\ 5/a\ 6 g g1 g1 b).
+
+(* Finally, a state y is reachable from x if either there is a single move 
+leading from x to y, or there is a safe state z such that z is reachable from x 
+and there is a move leading from z to y *)
+
+inductive reachable : \ 5a href="cic:/matita/tutorial/chapter1/state.ind(1,0,0)"\ 6state\ 5/a\ 6 → \ 5a href="cic:/matita/tutorial/chapter1/state.ind(1,0,0)"\ 6state\ 5/a\ 6 → Prop ≝
+| one : ∀x,y.\ 5a href="cic:/matita/tutorial/chapter1/move.ind(1,0,0)"\ 6move\ 5/a\ 6 x y → reachable x y
+| more : ∀x,z,y. \ 5span style="text-decoration: underline;"\ 6\ 5/span\ 6reachable x z → \ 5a href="cic:/matita/tutorial/chapter1/safe_state.ind(1,0,0)"\ 6safe_state\ 5/a\ 6 z → \ 5span style="text-decoration: underline;"\ 6\ 5/span\ 6\ 5a href="cic:/matita/tutorial/chapter1/move.ind(1,0,0)"\ 6move\ 5/a\ 6 z y → reachable x y.
+
+(* Remarkably, Matita is now able to solve the problem by itslef, provided
+you allow automation to exploit more resources. The command /n/ is similar to
+//, where n is a measure of this complexity: in particular it is a bound to
+the depth of the expected proof tree (more precisely, to the number of nested
+applicative nodes). In this case, there is a solution in six moves, and we
+need a few more applications to handle reachability, and side conditions. 
+The magic number to let automation work is, in this case, 9.  *)
+
+lemma problem: \ 5a href="cic:/matita/tutorial/chapter1/reachable.ind(1,0,0)"\ 6reachable\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/start.def(1)"\ 6start\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/end.def(1)"\ 6end\ 5/a\ 6.
+normalize /9/ qed. 
+
+(* Let us now try to derive the proof in a more interactive way. Of course, we
+expect to need several moves to transfer all items from a bank to the other, so 
+we should start our proof by applying "more".
+*)
+
+lemma problem1: \ 5a href="cic:/matita/tutorial/chapter1/reachable.ind(1,0,0)"\ 6reachable\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/start.def(1)"\ 6start\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/end.def(1)"\ 6end\ 5/a\ 6.
 normalize 
-@more [4: @move_goat || 3: //]
-@more [4: @move_boat || 3: //]  
-@more [4: @move_wolf || 3: //]
-@more [4: @move_goat || 3: //]
-@more [4: @move_cabbage || 3: //]
-@more [4: @move_boat || 3: //]
-@one //
-qed.
+@\ 5a href="cic:/matita/tutorial/chapter1/reachable.con(0,2,0)"\ 6more\ 5/a\ 6
 
+(* We have now four open subgoals:
+
+  X : STATE
+  Y : reachable [east,east,east,east] X
+  W : safe_state X
+  Z : move X [west,west,west,west]
+That is, we must guess a state X, such that this is reachable from start, it is 
+safe, and there is a move leading from X to end. All goals are active, that is
+emphasized by the fact that they are all red. Any command typed by the user is
+normally applied in parallel to all active goals, but clearly we must proceed 
+here is a different way for each of them. The way to do it, is by structuring
+the script using the following syntax: [...|... |...|...] where we typically have
+as many cells inside the brackets as the number of the active subgoals. The
+interesting point is that we can associate with the three symbol "[", "|" and
+"]" a small-step semantics that allow to execute them individually. In particular
+
+- the operator "[" opens a new focusing section for the currently active goals,
+  and focus on the first of them
+- the operator "|" shift the focus to the next goal
+- the operator "]" close the focusing section, falling back to the previous level
+  and adding to it all remaining goals not yet closed
+
+Let us see the effect of the "[" on our proof:
+*)
+
+  [  
+
+(* As you see, only the first goal has now the focus on. Moreover, all goals got
+a progressive numerical label, to help designating them, if needed. 
+We can now proceed in several possible ways. The most straightforward way is to 
+provide the intermediate state, that is [east,west,west,east]. We can do it, by 
+just applying this term. *)
+
+   @(\ 5a href="cic:/matita/tutorial/chapter1/state.con(0,1,0)"\ 6mk_state\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,1,0)"\ 6east\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,2,0)"\ 6west\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,2,0)"\ 6west\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,1,0)"\ 6east\ 5/a\ 6
+
+(* This application closes the goal; at present, no goal has the focus on.
+In order to act on the next goal, we must focus on it using the "|" operator. In
+this case, we would like to skip the next goal, and focus on the trivial third 
+subgoal: a simple way to do it, is by retyping "|". The proof that 
+[east,west,west,east] is safe is trivial and can be done with //.*)
+
+  || //
 
 (*
-definition move_item ≝ λs.λi:movable_item s.
-match (elem ? i) with
-[ goat ⇒ mk_state (change_side (goat_pos s)) (wolf_pos s) 
-  (cabbage_pos s) (change_side (boat_pos s))
-| wolf ⇒ mk_state (goat_pos s) (change_side (wolf_pos s)) 
-  (cabbage_pos s) (change_side (boat_pos s))
-| cabbage ⇒ mk_state (goat_pos s) (wolf_pos s) 
-  (change_side (cabbage_pos s)) (change_side (boat_pos s))
-| boat ⇒ mk_state (goat_pos s) (wolf_pos s) 
-  (cabbage_pos s) (change_side (boat_pos s))
-].
-
-definition legal_state ≝ λs. 
-  cabbage_pos s = goat_pos s ∨ 
-  goat_pos s = wolf_pos s → goat_pos s = boat_pos s.
-  
-definition legal_step ≝ λs1,s2. 
-  ∃i.move_item s1 i = s2. 
-
-inductive reachable : state → state → Prop ≝
-| nil : ∀s.reachable s s
-| step : ∀s1,s2,s3. legal_step s1 s2 → legal_state s2 → reachable s2 s3 →
-  reachable s1 s3. 
-
-definition second ≝ mk_state west east east west.
-definition end ≝ mk_state west west west west.
-
-lemma goat_move: ∀s.legal_step s (mk_state (change_side (goat_pos s)) (wolf_pos s) 
-  (cabbage_pos s) (change_side (boat_pos s))).
-
-lemma problem: reachable start second.
-@step [| @ex_intro  // [| @move_goat ] // | //]
-
-  [|| @move_goat //| //
-  |normalize
\ No newline at end of file
+We then advance to the next goal, namely the fact that there is a move from 
+[east,west,west,east] to [west,west,west,west]; this is trivial too, but it 
+requires /2/ since move_goat opens an additional subgoal. By applying "]" we
+refocus on the skipped goal, going back to a situation similar to the one we
+started with. *)
+
+  | /2/ ] 
+
+(* Let us perform the next step, namely moving back the boat, in a sligtly 
+different way. The more operation expects as second argument the new 
+intermediate state, hence instead of applying more we can apply its 
+instantiation (more ? (mk_state east west west west)). The question mark is 
+an implicit argument to be guessed by the system. *)
+
+\ 5span style="text-decoration: underline;"\ 6\ 5/span\ 6@(\ 5a href="cic:/matita/tutorial/chapter1/reachable.con(0,2,0)"\ 6more\ 5/a\ 6 ? (\ 5a href="cic:/matita/tutorial/chapter1/state.con(0,1,0)"\ 6mk_state\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,1,0)"\ 6east\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,2,0)"\ 6west\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,2,0)"\ 6west\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,2,0)"\ 6west\ 5/a\ 6)) 
+
+(* All subgoals are focused (they are all red). Two of them are trivial; we
+just call automation at level 2, and it will close both of them, taking
+us to the third move.*)
+
+  /2/ 
+
+(* We must now move the wolf. Suppose that, instead of specifying the next state 
+we prefer to specify the move. In the style of the previous move, this amounts
+to apply the term (more … (move_wolf … )) The dots are a convenient syntax to 
+express an arbitrary number of implicit parameters. *) 
+
+@(\ 5a href="cic:/matita/tutorial/chapter1/reachable.con(0,2,0)"\ 6more\ 5/a\ 6 … (\ 5a href="cic:/matita/tutorial/chapter1/move.con(0,2,0)"\ 6move_wolf\ 5/a\ 6 … ))
+
+(* Unfortunately this is not enough to fully instantiate the intermediate state.
+All goals still depend from an unknown bank B. Calling automation in this situation
+does not help since it refuses to close subgoals instantiating other - still 
+open - goals. A way to proceed is to focus on the fourth "bank" subgoal,
+instantiating it with the appropriate value, in this case east; then we close 
+focusing, and call automation. To focus on subgoal i, instead of typing "|" several
+times we can just write "i:" as described by the following command. *)
+
+  [4: @\ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,1,0)"\ 6east\ 5/a\ 6\ 5span style="text-decoration: underline;"\ 6\ 5/span\ 6]  /2/
+
+(* An alternative, simpler way is to instantiate each move with the destination
+bank. Let us complete the proof adopting this style. *)
+
+@(\ 5a href="cic:/matita/tutorial/chapter1/reachable.con(0,2,0)"\ 6more\ 5/a\ 6 … (\ 5a href="cic:/matita/tutorial/chapter1/move.con(0,1,0)"\ 6move_goat\ 5/a\ 6 \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,2,0)"\ 6west\ 5/a\ 6 … )) /2/
+@(\ 5a href="cic:/matita/tutorial/chapter1/reachable.con(0,2,0)"\ 6more\ 5/a\ 6 … (\ 5a href="cic:/matita/tutorial/chapter1/move.con(0,3,0)"\ 6move_cabbage\ 5/a\ 6 ?? \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,1,0)"\ 6east\ 5/a\ 6 … )) /2/
+@(\ 5a href="cic:/matita/tutorial/chapter1/reachable.con(0,2,0)"\ 6more\ 5/a\ 6 … (\ 5a href="cic:/matita/tutorial/chapter1/move.con(0,4,0)"\ 6move_boat\ 5/a\ 6 ??? \ 5a href="cic:/matita/tutorial/chapter1/bank.con(0,2,0)"\ 6west\ 5/a\ 6 …)) /2/   
+@\ 5a href="cic:/matita/tutorial/chapter1/reachable.con(0,1,0)"\ 6one\ 5/a\ 6 /2/
+qed.
\ No newline at end of file