Introduction
Earlier this year, I attended the Formal Methods for the Informal Engineer workshop, and found that quite fascinating. It is a huge field, and the topic is quite deep and dense, as one would expect. It was my first introduction to the interactive theorem prover Coq, during the nice tutorial by Cody Roux.
Some time later, after working thought the Logical Foundations book from the Software Foundations series, I wanted to try and practice it on my own on some toy problem. The “wolf, goat and cabbage problem” came to mind, and I have previously seems examples that show that the Alloy Analyzer and Z3 could be used to solve it automatically. But I could not find an equivalent solution in Coq. So I tried to see if I could do it with my current knowledge.
In my first attempt, I managed to model and reproduce a known solution as a proof! Or so I thought… The modeling had a problem which allowed for a “single step” nonsense solution. That was uncovered after I tried to use Coq’s proof automation to see if it worked. Then it showed me the bogus “solution”, and I had to rethink how to represent the problem.
The problem was that I was not constraining the contents of both river banks correctly during the crossing, so it was possible that a bank would suddenly change composition after a step. After constraining those values more, I could reproduce the known solution, but lost the ability to use the standard automation machinery… I guess I’d need to create my own version of the auto
or eauto
tactics, like Adam Chlipala’s crush
, but I don’t know how to do that quite yet.
Even with this second solution, there some issues with it and I’m still not sure if it is correct, since the first time and it was not obvious to me that I had messed up. I’ll share both solutions below, and maybe one day someone can give me some hints on how to fix and correct those issues.
I should also say that I used Alectryon by Clément Pit-Claudel to produce the Coq snippets with proof states below, and it is quite magical. That, in turn, was taken from Philip Zucker’s post about translating his Z3 tutorial from the FMIE workshop to Coq. If you hover your cursor over the proof lines, it should show the hypothesis and the goals at that point.
Basic definitions
The definition below did not change between attempts, and were shared by both solutions.
First, we need to import some modules so we can use a notation for list literals. This is an amazing feature of Coq: the ability to define custom notation.
From Coq Require Import Lists.List. Import ListNotations.
Then, we define the “objects” that the farmer wants to take from one river bank to the other. Maybe it’s strange to call a wolf and a goat objects, but I couldn’t think of another name for the type, and I went with the nomenclature from the Alloy tutorial.
Inductive Object :=
| Wolf
| Goat
| Cabbage.
In each step, the farmer must cross from one side of the river to the other alone or carrying one of the objects. I modeled the state of the problem by defining which is the river bank the farmer will go to next: either the left or the right side of the river.
Inductive Direction :=
| Right
| Left.
But some pairs of objects cannot be left unattended, else they eat each other. Those pairs are “forbidden” when crossing the river. The eats
function tells us if either of two objects eats the other, and the NoEats
predicate uses that to assert that list of objects, representing one side of the river, contains no forbidden pairs of objects.
Definition eats (o1 o2 : Object) : bool := match (o1, o2) with | (Wolf, Goat) => true | (Goat, Wolf) => true | (Goat, Cabbage) => true | (Cabbage, Goat) => true | _ => false end. Inductive NoEats : list Object -> Prop := | NoEatsNil : NoEats [] | NoEatsOne : forall o, NoEats [o] | NoEatsMore : forall o os, NoEats os -> forallb (eats o) os = false -> NoEats (o :: os).
First attempt (problematic!)
Module FirstAttempt.
The RiverCrossing
predicate represents the state of the problem. It is parameterized by the direction the farmer is going next, the contents of the left and the right river banks. Then comes the constructors of this predicate.
We have the initial state, where all objects are on the left bank, the right bank is empty, and the farmer is going right. I used the In
predicate to avoid having to deal with specific list orderings.
Then the farmer can go right or left, alone. In that case, the contents of both banks do not change, but we must enforce that the objects that were just left alone do not eat each other.
Else, the farmer takes one object along the trip. I just checked that the object being carried exists on the source bank in the initial state and disappears from there in the final state, and that the remaining objects don’t eat each other. This has the problem I alluded before: the constraints on the initial and final compositions of each river bank are too loose, allowing for “quantum jumps”.
Inductive RiverCrossing :
Direction -> list Object -> list Object -> Prop :=
| initial : forall l,
In Wolf l ->
In Goat l ->
In Cabbage l ->
RiverCrossing Right l []
| goRightAlone :
forall l r,
NoEats l -> RiverCrossing Right l r ->
RiverCrossing Left l r
| goLeftAlone :
forall l r,
NoEats r -> RiverCrossing Left l r ->
RiverCrossing Right l r
| goRight :
forall o l r l' r',
In o l -> ~ (In o l') -> In o r' -> NoEats l' ->
RiverCrossing Right l r ->
RiverCrossing Left l' r'
| goLeft :
forall o l r l' r',
In o r -> ~ (In o r') -> In o l' -> NoEats r' ->
RiverCrossing Left l r ->
RiverCrossing Right l' r'.
For reference, I’ll just reproduce the proof using this model below, but beware that it is wrong, as said before. Also, another thing of notice is that the steps are “backwards”: we start from the final state (everything in the right bank) and work our way towards the initial state, which should be the only way to produce a RiverCrossing
out of thin air.
forall r : list Object, In Wolf r -> In Goat r -> In Cabbage r -> RiverCrossing Left [] rforall r : list Object, In Wolf r -> In Goat r -> In Cabbage r -> RiverCrossing Left [] r(* step 7 : [G] -G> [W; C] => [] || [G; W; C] *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [] r(* Goat in initial left bank *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Goat [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r~ In Goat []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Goat rr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat] [Cabbage; Wolf](* Goat not in final left bank *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r~ In Goat []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Goat rr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat] [Cabbage; Wolf](* Goat in final right bank *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Goat rr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat] [Cabbage; Wolf](* final left bank is empty, so it's safe *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat] [Cabbage; Wolf](* step 6 : [G] <- [W; C] => [G] || [W; C] *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat] [Cabbage; Wolf](* proof that Wolf doesn't eat Cabbage *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Cabbage; Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Goat] [Cabbage; Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rforallb (eats Cabbage) [Wolf] = falser: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Goat] [Cabbage; Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rforallb (eats Cabbage) [Wolf] = falser: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Goat] [Cabbage; Wolf](* step 5 : [C; G] -C> [W] => [G] || [W; C] *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Goat] [Cabbage; Wolf](* Cabbage in initial left bank *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Cabbage [Cabbage; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r~ In Cabbage [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Cabbage [Cabbage; Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Cabbage; Goat] [Wolf](* Cabbage not in final left bank *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r~ In Cabbage [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Cabbage [Cabbage; Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Cabbage; Goat] [Wolf](* Cabbage in final right bank *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Cabbage [Cabbage; Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Cabbage; Goat] [Wolf](* final left bank just has the Goat, so it's safe *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Cabbage; Goat] [Wolf](* step 4 : [C] <G- [W; G] => [C; G] || [W] *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Cabbage; Goat] [Wolf](* Goat in initial right bank *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Goat [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r~ In Goat [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Goat [Cabbage; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Cabbage] [Wolf; Goat](* Goat not in final right bank *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r~ In Goat [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Goat [Cabbage; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Cabbage] [Wolf; Goat](* Goat in final Left bank *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Goat [Cabbage; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Cabbage] [Wolf; Goat](* final right bank just has the Wolf, so it's safe *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Cabbage] [Wolf; Goat](* step 3 : [W; C] -W> [G] => [C] || [W; G] *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Cabbage] [Wolf; Goat](* Wolf in initial left bank *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Wolf [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r~ In Wolf [Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Wolf [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Cabbage] [Goat](* Wolf not in final left bank *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r~ In Wolf [Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Wolf [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Cabbage] [Goat](* Wolf in final right bank *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Wolf [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Cabbage] [Goat](* final left bank just has the Cabbage, so it's safe *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Cabbage] [Goat](* step 2 : [W; C] <- [G] => [W; C] || [G] *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Cabbage] [Goat](* proof that Goat doesn't eat itself *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Wolf; Cabbage] [Goat](* step 1 : [W; G; C] -G> [] => [W; C] || [G] *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Wolf; Cabbage] [Goat](* Goat in initial left bank *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Goat [Wolf; Goat; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r~ In Goat [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Goat [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] [](* Goat not in final left bank *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r~ In Goat [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Goat [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] [](* Goat in final right bank *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Goat [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] [](* proof that Wolf doesn't eat Cabbage *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rforallb (eats Wolf) [Cabbage] = falser: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rforallb (eats Wolf) [Cabbage] = falser: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] [](* initial state: everyone on the left bank *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] [](* Wolf on the initial left bank *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Wolf [Wolf; Goat; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Goat [Wolf; Goat; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Cabbage [Wolf; Goat; Cabbage](* Goat on the initial left bank *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Goat [Wolf; Goat; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Cabbage [Wolf; Goat; Cabbage](* Cabbage on the initial left bank *) simpl; right; right; left; reflexivity. Qed.r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Cabbage [Wolf; Goat; Cabbage]
I was quite satisfied that this worked out, but luckily that model was amenable to simple proof automation. Using the info_eauto
tactic, it proved that the objects could go all to the right side… But by a strange path…
I also needed to add the constructors and functions relevant to the problem in a hint database called local
so that eauto
could use them.
forall r : list Object, In Wolf r -> In Goat r -> In Cabbage r -> RiverCrossing Left [] rforall r : list Object, In Wolf r -> In Goat r -> In Cabbage r -> RiverCrossing Left [] rQed.forall r : list Object, In Wolf r -> In Goat r -> In Cabbage r -> RiverCrossing Left [] r(* found by eauto *)forall r : list Object, In Wolf r -> In Goat r -> In Cabbage r -> RiverCrossing Left [] rr: list ObjectIn Wolf r -> In Goat r -> In Cabbage r -> RiverCrossing Left [] rr: list Object
H: In Wolf rIn Goat r -> In Cabbage r -> RiverCrossing Left [] rr: list Object
H: In Wolf r
H0: In Goat rIn Cabbage r -> RiverCrossing Left [] rr: list Object
H: In Wolf r
H0: In Goat r
H1: In Cabbage rRiverCrossing Left [] rr: list Object
H: In Wolf r
H0: In Goat r
H1: In Cabbage rIn ?o ?lr: list Object
H: In Wolf r
H0: In Goat r
H1: In Cabbage r~ In ?o []r: list Object
H: In Wolf r
H0: In Goat r
H1: In Cabbage rIn ?o rr: list Object
H: In Wolf r
H0: In Goat r
H1: In Cabbage rNoEats []r: list Object
H: In Wolf r
H0: In Goat r
H1: In Cabbage rRiverCrossing Right ?l ?rr: list Object
H: In Wolf r
H0: In Goat r
H1: In Cabbage r~ In Cabbage []r: list Object
H: In Wolf r
H0: In Goat r
H1: In Cabbage rIn Cabbage rr: list Object
H: In Wolf r
H0: In Goat r
H1: In Cabbage rNoEats []r: list Object
H: In Wolf r
H0: In Goat r
H1: In Cabbage rRiverCrossing Right r ?rr: list Object
H: In Wolf r
H0: In Goat r
H1: In Cabbage rIn Cabbage rr: list Object
H: In Wolf r
H0: In Goat r
H1: In Cabbage rNoEats []r: list Object
H: In Wolf r
H0: In Goat r
H1: In Cabbage rRiverCrossing Right r ?rr: list Object
H: In Wolf r
H0: In Goat r
H1: In Cabbage rNoEats []r: list Object
H: In Wolf r
H0: In Goat r
H1: In Cabbage rRiverCrossing Right r ?r(* oh no *)r: list Object
H: In Wolf r
H0: In Goat r
H1: In Cabbage rRiverCrossing Right r ?rr: list Object
H: In Wolf r
H0: In Goat r
H1: In Cabbage rIn Wolf rr: list Object
H: In Wolf r
H0: In Goat r
H1: In Cabbage rIn Goat rr: list Object
H: In Wolf r
H0: In Goat r
H1: In Cabbage rIn Cabbage rr: list Object
H: In Wolf r
H0: In Goat r
H1: In Cabbage rIn Goat rr: list Object
H: In Wolf r
H0: In Goat r
H1: In Cabbage rIn Cabbage rexact H1. Qed. End FirstAttempt.r: list Object
H: In Wolf r
H0: In Goat r
H1: In Cabbage rIn Cabbage r
Second attempt
Module SecondAttempt.
In my second attempt, I only changed the goRight
and goLeft
constructors to tighten up the restrictions on the contents of both river banks. Anything on the opposing side in the initial state should still be present in the final state plus the object that just crossed. The initial side should contain a special object, the one being carried, and all objects in that side should be present there in the final state, except the carried object. This was the essential change.
Inductive RiverCrossing : Direction -> list Object -> list Object -> Prop := | initial : forall l, In Wolf l -> In Goat l -> In Cabbage l -> RiverCrossing Right l [] | goRightAlone : forall l r, NoEats l -> RiverCrossing Right l r -> RiverCrossing Left l r | goLeftAlone : forall l r, NoEats r -> RiverCrossing Left l r -> RiverCrossing Right l r | goRight : forall l r l' r', (exists o, In o l /\ ~ (In o r) /\ (forall ol, In ol l -> (ol = o /\ In ol r') \/ (ol <> o /\ In ol l' /\ ~(In ol r'))) /\ (forall or, (In or r -> (or <> o /\ In or r')))) -> NoEats l' -> RiverCrossing Right l r -> RiverCrossing Left l' r' | goLeft : forall l r l' r', (exists o, In o r /\ ~ (In o l) /\ (forall or, In or r -> (or = o /\ In or l') \/ (or <> o /\ In or r' /\ ~(In or l'))) /\ (forall ol, (In ol l -> (ol <> o /\ In ol l')))) -> NoEats r' -> RiverCrossing Left l r -> RiverCrossing Right l' r'.
Unfortunately, with those changes, neither auto
nor eauto
work anymore. There are some goals that are repeated during the proof, especially regarding goals and hypothesis of the forms In X Xs
and ~ (In X Xs)
. Using some excerpts from the CPDT and PLF books, I managed to make some rudimentary automated tactics for those cases.
Ltac auto_not_in := repeat match goal with | |- ~ (In ?X ?Xs) => intros contra; repeat (destruct contra as [contra | contra]; try discriminate; try apply contra); try destruct contra end. Ltac not_in_absurd H := match type of H with | In _ [] => exfalso; apply in_nil in H; apply H | In _ _ => let H0 := fresh "H0" in try (inversion H as [H0 | H0]; try discriminate; not_in_absurd H0) end. (* taken from: https://softwarefoundations.cis.upenn.edu/plf-current/LibTactics.html#lab524 *) Ltac jauto_set_hyps := repeat match goal with H: ?T |- _ => match T with | _ /\ _ => destruct H | exists a, _ => destruct H | _ => generalize H; clear H end end. Ltac jauto_set_goal := repeat match goal with | |- exists a, _ => esplit | |- _ /\ _ => split end. Ltac jauto_set := intros; jauto_set_hyps; intros; jauto_set_goal; unfold not in *. Tactic Notation "jauto" := try solve [ jauto_set; eauto with local ]; try auto_not_in. Tactic Notation "jauto_fast" := try solve [ auto with local | eauto with local | jauto ].
Armed with that, I redid my solution from before. Alas, I’m not able at the moment to check if there are bogus solutions as I did before… Again, I’ll just reproduce the solution below.
forall r : list Object, In Wolf r -> In Goat r -> In Cabbage r -> RiverCrossing Left [] rforall r : list Object, In Wolf r -> In Goat r -> In Cabbage r -> RiverCrossing Left [] r(* step 7 : [G] -G> [W; C] => [] || [G; W; C] *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [] rr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rexists o : Object, In o [Goat] /\ ~ In o [Wolf; Cabbage] /\ (forall ol : Object, In ol [Goat] -> ol = o /\ In ol r \/ ol <> o /\ In ol [] /\ ~ In ol r) /\ (forall or : Object, In or [Wolf; Cabbage] -> or <> o /\ In or r)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat] [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Goat [Goat] /\ ~ In Goat [Wolf; Cabbage] /\ (forall ol : Object, In ol [Goat] -> ol = Goat /\ In ol r \/ ol <> Goat /\ In ol [] /\ ~ In ol r) /\ (forall or : Object, In or [Wolf; Cabbage] -> or <> Goat /\ In or r)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat] [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rforall ol : Object, In ol [Goat] -> ol = Goat /\ In ol r \/ ol <> Goat /\ In ol [] /\ ~ In ol rr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf; Cabbage]or <> Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf; Cabbage]In or rr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat] [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Goat]Goat = Goat /\ In Goat r \/ Goat <> Goat /\ In Goat [] /\ ~ In Goat rr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf; Cabbage]or <> Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf; Cabbage]In or rr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat] [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Goat]Goat = Goat /\ In Goat rr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf; Cabbage]or <> Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf; Cabbage]In or rr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat] [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Goat]Goat = Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Goat]In Goat rr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf; Cabbage]or <> Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf; Cabbage]In or rr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat] [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Goat]In Goat rr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf; Cabbage]or <> Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf; Cabbage]In or rr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat] [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf; Cabbage]or <> Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf; Cabbage]In or rr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat] [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf; Cabbage]In or rr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat] [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Wolf [Wolf; Cabbage]In Wolf rr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Cabbage]
H0: In Cabbage [Cabbage]In Cabbage rr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat] [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Cabbage]
H0: In Cabbage [Cabbage]In Cabbage rr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat] [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat] [Wolf; Cabbage](* step 6 : [G] <- [W; C] => [G] || [W; C] *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat] [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Goat] [Wolf; Cabbage](* step 5 : [C; G] -C> [W] => [G] || [W; C] *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Goat] [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rexists o : Object, In o [Goat; Cabbage] /\ ~ In o [Wolf] /\ (forall ol : Object, In ol [Goat; Cabbage] -> ol = o /\ In ol [Wolf; Cabbage] \/ ol <> o /\ In ol [Goat] /\ ~ In ol [Wolf; Cabbage]) /\ (forall or : Object, In or [Wolf] -> or <> o /\ In or [Wolf; Cabbage])r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat; Cabbage] [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Cabbage [Goat; Cabbage] /\ ~ In Cabbage [Wolf] /\ (forall ol : Object, In ol [Goat; Cabbage] -> ol = Cabbage /\ In ol [Wolf; Cabbage] \/ ol <> Cabbage /\ In ol [Goat] /\ ~ In ol [Wolf; Cabbage]) /\ (forall or : Object, In or [Wolf] -> or <> Cabbage /\ In or [Wolf; Cabbage])r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat; Cabbage] [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rforall ol : Object, In ol [Goat; Cabbage] -> ol = Cabbage /\ In ol [Wolf; Cabbage] \/ ol <> Cabbage /\ In ol [Goat] /\ ~ In ol [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]or <> Cabbager: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]In or [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat; Cabbage] [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Goat; Cabbage]Goat = Cabbage /\ In Goat [Wolf; Cabbage] \/ Goat <> Cabbage /\ In Goat [Goat] /\ ~ In Goat [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Goat; Cabbage]
H0: In Cabbage [Cabbage]Cabbage = Cabbage /\ In Cabbage [Wolf; Cabbage] \/ Cabbage <> Cabbage /\ In Cabbage [Goat] /\ ~ In Cabbage [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]or <> Cabbager: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]In or [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat; Cabbage] [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Goat; Cabbage]Goat <> Cabbage /\ In Goat [Goat] /\ ~ In Goat [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Goat; Cabbage]
H0: In Cabbage [Cabbage]Cabbage = Cabbage /\ In Cabbage [Wolf; Cabbage] \/ Cabbage <> Cabbage /\ In Cabbage [Goat] /\ ~ In Cabbage [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]or <> Cabbager: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]In or [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat; Cabbage] [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Goat; Cabbage]Goat <> Cabbager: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Goat; Cabbage]In Goat [Goat] /\ ~ In Goat [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Goat; Cabbage]
H0: In Cabbage [Cabbage]Cabbage = Cabbage /\ In Cabbage [Wolf; Cabbage] \/ Cabbage <> Cabbage /\ In Cabbage [Goat] /\ ~ In Cabbage [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]or <> Cabbager: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]In or [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat; Cabbage] [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Goat; Cabbage]In Goat [Goat] /\ ~ In Goat [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Goat; Cabbage]
H0: In Cabbage [Cabbage]Cabbage = Cabbage /\ In Cabbage [Wolf; Cabbage] \/ Cabbage <> Cabbage /\ In Cabbage [Goat] /\ ~ In Cabbage [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]or <> Cabbager: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]In or [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat; Cabbage] [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Goat; Cabbage]In Goat [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Goat; Cabbage]~ In Goat [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Goat; Cabbage]
H0: In Cabbage [Cabbage]Cabbage = Cabbage /\ In Cabbage [Wolf; Cabbage] \/ Cabbage <> Cabbage /\ In Cabbage [Goat] /\ ~ In Cabbage [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]or <> Cabbager: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]In or [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat; Cabbage] [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Goat; Cabbage]~ In Goat [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Goat; Cabbage]
H0: In Cabbage [Cabbage]Cabbage = Cabbage /\ In Cabbage [Wolf; Cabbage] \/ Cabbage <> Cabbage /\ In Cabbage [Goat] /\ ~ In Cabbage [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]or <> Cabbager: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]In or [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat; Cabbage] [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Goat; Cabbage]
H0: In Cabbage [Cabbage]Cabbage = Cabbage /\ In Cabbage [Wolf; Cabbage] \/ Cabbage <> Cabbage /\ In Cabbage [Goat] /\ ~ In Cabbage [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]or <> Cabbager: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]In or [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat; Cabbage] [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Goat; Cabbage]
H0: In Cabbage [Cabbage]Cabbage = Cabbage /\ In Cabbage [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]or <> Cabbager: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]In or [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat; Cabbage] [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Goat; Cabbage]
H0: In Cabbage [Cabbage]Cabbage = Cabbager: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Goat; Cabbage]
H0: In Cabbage [Cabbage]In Cabbage [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]or <> Cabbager: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]In or [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat; Cabbage] [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Goat; Cabbage]
H0: In Cabbage [Cabbage]In Cabbage [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]or <> Cabbager: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]In or [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat; Cabbage] [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]or <> Cabbager: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]In or [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat; Cabbage] [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Wolf]In or [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat; Cabbage] [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Wolf [Wolf]In Wolf [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat; Cabbage] [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat; Cabbage] [Wolf](* step 4 : [C] <G- [W; G] => [C; G] || [W] *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Goat; Cabbage] [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rexists o : Object, In o [Wolf; Goat] /\ ~ In o [Cabbage] /\ (forall or0 : Object, In or0 [Wolf; Goat] -> or0 = o /\ In or0 [Goat; Cabbage] \/ or0 <> o /\ In or0 [Wolf] /\ ~ In or0 [Goat; Cabbage]) /\ (forall ol : Object, In ol [Cabbage] -> ol <> o /\ In ol [Goat; Cabbage])r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Cabbage] [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Goat [Wolf; Goat] /\ ~ In Goat [Cabbage] /\ (forall or0 : Object, In or0 [Wolf; Goat] -> or0 = Goat /\ In or0 [Goat; Cabbage] \/ or0 <> Goat /\ In or0 [Wolf] /\ ~ In or0 [Goat; Cabbage]) /\ (forall ol : Object, In ol [Cabbage] -> ol <> Goat /\ In ol [Goat; Cabbage])r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Cabbage] [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rforall or0 : Object, In or0 [Wolf; Goat] -> or0 = Goat /\ In or0 [Goat; Cabbage] \/ or0 <> Goat /\ In or0 [Wolf] /\ ~ In or0 [Goat; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
ol: Object
H: In ol [Cabbage]ol <> Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Cabbage] [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Wolf [Wolf; Goat]Wolf = Goat /\ In Wolf [Goat; Cabbage] \/ Wolf <> Goat /\ In Wolf [Wolf] /\ ~ In Wolf [Goat; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Wolf; Goat]
H0: In Goat [Goat]Goat = Goat /\ In Goat [Goat; Cabbage] \/ Goat <> Goat /\ In Goat [Wolf] /\ ~ In Goat [Goat; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
ol: Object
H: In ol [Cabbage]ol <> Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Cabbage] [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Wolf [Wolf; Goat]Wolf <> Goat /\ In Wolf [Wolf] /\ ~ In Wolf [Goat; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Wolf; Goat]
H0: In Goat [Goat]Goat = Goat /\ In Goat [Goat; Cabbage] \/ Goat <> Goat /\ In Goat [Wolf] /\ ~ In Goat [Goat; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
ol: Object
H: In ol [Cabbage]ol <> Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Cabbage] [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Wolf [Wolf; Goat]Wolf <> Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Wolf [Wolf; Goat]In Wolf [Wolf] /\ ~ In Wolf [Goat; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Wolf; Goat]
H0: In Goat [Goat]Goat = Goat /\ In Goat [Goat; Cabbage] \/ Goat <> Goat /\ In Goat [Wolf] /\ ~ In Goat [Goat; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
ol: Object
H: In ol [Cabbage]ol <> Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Cabbage] [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Wolf [Wolf; Goat]In Wolf [Wolf] /\ ~ In Wolf [Goat; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Wolf; Goat]
H0: In Goat [Goat]Goat = Goat /\ In Goat [Goat; Cabbage] \/ Goat <> Goat /\ In Goat [Wolf] /\ ~ In Goat [Goat; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
ol: Object
H: In ol [Cabbage]ol <> Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Cabbage] [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Wolf [Wolf; Goat]In Wolf [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Wolf [Wolf; Goat]~ In Wolf [Goat; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Wolf; Goat]
H0: In Goat [Goat]Goat = Goat /\ In Goat [Goat; Cabbage] \/ Goat <> Goat /\ In Goat [Wolf] /\ ~ In Goat [Goat; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
ol: Object
H: In ol [Cabbage]ol <> Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Cabbage] [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Wolf [Wolf; Goat]~ In Wolf [Goat; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Wolf; Goat]
H0: In Goat [Goat]Goat = Goat /\ In Goat [Goat; Cabbage] \/ Goat <> Goat /\ In Goat [Wolf] /\ ~ In Goat [Goat; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
ol: Object
H: In ol [Cabbage]ol <> Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Cabbage] [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Wolf; Goat]
H0: In Goat [Goat]Goat = Goat /\ In Goat [Goat; Cabbage] \/ Goat <> Goat /\ In Goat [Wolf] /\ ~ In Goat [Goat; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
ol: Object
H: In ol [Cabbage]ol <> Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Cabbage] [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Wolf; Goat]
H0: In Goat [Goat]Goat = Goat /\ In Goat [Goat; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
ol: Object
H: In ol [Cabbage]ol <> Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Cabbage] [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Wolf; Goat]
H0: In Goat [Goat]Goat = Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Wolf; Goat]
H0: In Goat [Goat]In Goat [Goat; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
ol: Object
H: In ol [Cabbage]ol <> Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Cabbage] [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Wolf; Goat]
H0: In Goat [Goat]In Goat [Goat; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
ol: Object
H: In ol [Cabbage]ol <> Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Cabbage] [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
ol: Object
H: In ol [Cabbage]ol <> Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Cabbage] [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Cabbage] [Wolf; Goat](* step 3 : [W; C] -W> [G] => [C] || [W; G] *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Cabbage] [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rexists o : Object, In o [Wolf; Cabbage] /\ ~ In o [Goat] /\ (forall ol : Object, In ol [Wolf; Cabbage] -> ol = o /\ In ol [Wolf; Goat] \/ ol <> o /\ In ol [Cabbage] /\ ~ In ol [Wolf; Goat]) /\ (forall or : Object, In or [Goat] -> or <> o /\ In or [Wolf; Goat])r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Cabbage] [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Wolf [Wolf; Cabbage] /\ ~ In Wolf [Goat] /\ (forall ol : Object, In ol [Wolf; Cabbage] -> ol = Wolf /\ In ol [Wolf; Goat] \/ ol <> Wolf /\ In ol [Cabbage] /\ ~ In ol [Wolf; Goat]) /\ (forall or : Object, In or [Goat] -> or <> Wolf /\ In or [Wolf; Goat])r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Cabbage] [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rforall ol : Object, In ol [Wolf; Cabbage] -> ol = Wolf /\ In ol [Wolf; Goat] \/ ol <> Wolf /\ In ol [Cabbage] /\ ~ In ol [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Goat]or <> Wolfr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Cabbage] [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Wolf [Wolf; Cabbage]Wolf = Wolf /\ In Wolf [Wolf; Goat] \/ Wolf <> Wolf /\ In Wolf [Cabbage] /\ ~ In Wolf [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Cabbage]
H0: In Cabbage [Cabbage]Cabbage = Wolf /\ In Cabbage [Wolf; Goat] \/ Cabbage <> Wolf /\ In Cabbage [Cabbage] /\ ~ In Cabbage [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Goat]or <> Wolfr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Cabbage] [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Wolf [Wolf; Cabbage]Wolf = Wolf /\ In Wolf [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Cabbage]
H0: In Cabbage [Cabbage]Cabbage = Wolf /\ In Cabbage [Wolf; Goat] \/ Cabbage <> Wolf /\ In Cabbage [Cabbage] /\ ~ In Cabbage [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Goat]or <> Wolfr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Cabbage] [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Wolf [Wolf; Cabbage]Wolf = Wolfr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Wolf [Wolf; Cabbage]In Wolf [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Cabbage]
H0: In Cabbage [Cabbage]Cabbage = Wolf /\ In Cabbage [Wolf; Goat] \/ Cabbage <> Wolf /\ In Cabbage [Cabbage] /\ ~ In Cabbage [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Goat]or <> Wolfr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Cabbage] [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Wolf [Wolf; Cabbage]In Wolf [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Cabbage]
H0: In Cabbage [Cabbage]Cabbage = Wolf /\ In Cabbage [Wolf; Goat] \/ Cabbage <> Wolf /\ In Cabbage [Cabbage] /\ ~ In Cabbage [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Goat]or <> Wolfr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Cabbage] [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Cabbage]
H0: In Cabbage [Cabbage]Cabbage = Wolf /\ In Cabbage [Wolf; Goat] \/ Cabbage <> Wolf /\ In Cabbage [Cabbage] /\ ~ In Cabbage [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Goat]or <> Wolfr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Cabbage] [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Cabbage]
H0: In Cabbage [Cabbage]Cabbage <> Wolf /\ In Cabbage [Cabbage] /\ ~ In Cabbage [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Goat]or <> Wolfr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Cabbage] [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Cabbage]
H0: In Cabbage [Cabbage]Cabbage <> Wolfr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Cabbage]
H0: In Cabbage [Cabbage]In Cabbage [Cabbage] /\ ~ In Cabbage [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Goat]or <> Wolfr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Cabbage] [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Cabbage]
H0: In Cabbage [Cabbage]In Cabbage [Cabbage] /\ ~ In Cabbage [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Goat]or <> Wolfr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Cabbage] [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Cabbage]
H0: In Cabbage [Cabbage]In Cabbage [Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Cabbage]
H0: In Cabbage [Cabbage]~ In Cabbage [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Goat]or <> Wolfr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Cabbage] [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Cabbage]
H0: In Cabbage [Cabbage]~ In Cabbage [Wolf; Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Goat]or <> Wolfr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Cabbage] [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
or: Object
H: In or [Goat]or <> Wolfr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Cabbage] [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Cabbage] [Goat](* step 2 : [W; C] <- [G] => [W; C] || [G] *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Cabbage] [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Wolf; Cabbage] [Goat](* step 1 : [W; G; C] -G> [] => [W; C] || [G] *)r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Left [Wolf; Cabbage] [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rexists o : Object, In o [Wolf; Goat; Cabbage] /\ ~ In o [] /\ (forall ol : Object, In ol [Wolf; Goat; Cabbage] -> ol = o /\ In ol [Goat] \/ ol <> o /\ In ol [Wolf; Cabbage] /\ ~ In ol [Goat]) /\ (forall or : Object, In or [] -> or <> o /\ In or [Goat])r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rIn Goat [Wolf; Goat; Cabbage] /\ ~ In Goat [] /\ (forall ol : Object, In ol [Wolf; Goat; Cabbage] -> ol = Goat /\ In ol [Goat] \/ ol <> Goat /\ In ol [Wolf; Cabbage] /\ ~ In ol [Goat]) /\ (forall or : Object, In or [] -> or <> Goat /\ In or [Goat])r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rforall ol : Object, In ol [Wolf; Goat; Cabbage] -> ol = Goat /\ In ol [Goat] \/ ol <> Goat /\ In ol [Wolf; Cabbage] /\ ~ In ol [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Wolf [Wolf; Goat; Cabbage]Wolf = Goat /\ In Wolf [Goat] \/ Wolf <> Goat /\ In Wolf [Wolf; Cabbage] /\ ~ In Wolf [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Wolf; Goat; Cabbage]
H0: In Goat [Goat; Cabbage]Goat = Goat /\ In Goat [Goat] \/ Goat <> Goat /\ In Goat [Wolf; Cabbage] /\ ~ In Goat [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Goat; Cabbage]
H0: In Cabbage [Goat; Cabbage]
H1: In Cabbage [Cabbage]Cabbage = Goat /\ In Cabbage [Goat] \/ Cabbage <> Goat /\ In Cabbage [Wolf; Cabbage] /\ ~ In Cabbage [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Wolf [Wolf; Goat; Cabbage]Wolf <> Goat /\ In Wolf [Wolf; Cabbage] /\ ~ In Wolf [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Wolf; Goat; Cabbage]
H0: In Goat [Goat; Cabbage]Goat = Goat /\ In Goat [Goat] \/ Goat <> Goat /\ In Goat [Wolf; Cabbage] /\ ~ In Goat [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Goat; Cabbage]
H0: In Cabbage [Goat; Cabbage]
H1: In Cabbage [Cabbage]Cabbage = Goat /\ In Cabbage [Goat] \/ Cabbage <> Goat /\ In Cabbage [Wolf; Cabbage] /\ ~ In Cabbage [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Wolf [Wolf; Goat; Cabbage]Wolf <> Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Wolf [Wolf; Goat; Cabbage]In Wolf [Wolf; Cabbage] /\ ~ In Wolf [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Wolf; Goat; Cabbage]
H0: In Goat [Goat; Cabbage]Goat = Goat /\ In Goat [Goat] \/ Goat <> Goat /\ In Goat [Wolf; Cabbage] /\ ~ In Goat [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Goat; Cabbage]
H0: In Cabbage [Goat; Cabbage]
H1: In Cabbage [Cabbage]Cabbage = Goat /\ In Cabbage [Goat] \/ Cabbage <> Goat /\ In Cabbage [Wolf; Cabbage] /\ ~ In Cabbage [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Wolf [Wolf; Goat; Cabbage]In Wolf [Wolf; Cabbage] /\ ~ In Wolf [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Wolf; Goat; Cabbage]
H0: In Goat [Goat; Cabbage]Goat = Goat /\ In Goat [Goat] \/ Goat <> Goat /\ In Goat [Wolf; Cabbage] /\ ~ In Goat [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Goat; Cabbage]
H0: In Cabbage [Goat; Cabbage]
H1: In Cabbage [Cabbage]Cabbage = Goat /\ In Cabbage [Goat] \/ Cabbage <> Goat /\ In Cabbage [Wolf; Cabbage] /\ ~ In Cabbage [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Wolf [Wolf; Goat; Cabbage]In Wolf [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Wolf [Wolf; Goat; Cabbage]~ In Wolf [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Wolf; Goat; Cabbage]
H0: In Goat [Goat; Cabbage]Goat = Goat /\ In Goat [Goat] \/ Goat <> Goat /\ In Goat [Wolf; Cabbage] /\ ~ In Goat [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Goat; Cabbage]
H0: In Cabbage [Goat; Cabbage]
H1: In Cabbage [Cabbage]Cabbage = Goat /\ In Cabbage [Goat] \/ Cabbage <> Goat /\ In Cabbage [Wolf; Cabbage] /\ ~ In Cabbage [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Wolf [Wolf; Goat; Cabbage]~ In Wolf [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Wolf; Goat; Cabbage]
H0: In Goat [Goat; Cabbage]Goat = Goat /\ In Goat [Goat] \/ Goat <> Goat /\ In Goat [Wolf; Cabbage] /\ ~ In Goat [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Goat; Cabbage]
H0: In Cabbage [Goat; Cabbage]
H1: In Cabbage [Cabbage]Cabbage = Goat /\ In Cabbage [Goat] \/ Cabbage <> Goat /\ In Cabbage [Wolf; Cabbage] /\ ~ In Cabbage [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Wolf; Goat; Cabbage]
H0: In Goat [Goat; Cabbage]Goat = Goat /\ In Goat [Goat] \/ Goat <> Goat /\ In Goat [Wolf; Cabbage] /\ ~ In Goat [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Goat; Cabbage]
H0: In Cabbage [Goat; Cabbage]
H1: In Cabbage [Cabbage]Cabbage = Goat /\ In Cabbage [Goat] \/ Cabbage <> Goat /\ In Cabbage [Wolf; Cabbage] /\ ~ In Cabbage [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Wolf; Goat; Cabbage]
H0: In Goat [Goat; Cabbage]Goat = Goat /\ In Goat [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Goat; Cabbage]
H0: In Cabbage [Goat; Cabbage]
H1: In Cabbage [Cabbage]Cabbage = Goat /\ In Cabbage [Goat] \/ Cabbage <> Goat /\ In Cabbage [Wolf; Cabbage] /\ ~ In Cabbage [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Wolf; Goat; Cabbage]
H0: In Goat [Goat; Cabbage]Goat = Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Wolf; Goat; Cabbage]
H0: In Goat [Goat; Cabbage]In Goat [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Goat; Cabbage]
H0: In Cabbage [Goat; Cabbage]
H1: In Cabbage [Cabbage]Cabbage = Goat /\ In Cabbage [Goat] \/ Cabbage <> Goat /\ In Cabbage [Wolf; Cabbage] /\ ~ In Cabbage [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Goat [Wolf; Goat; Cabbage]
H0: In Goat [Goat; Cabbage]In Goat [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Goat; Cabbage]
H0: In Cabbage [Goat; Cabbage]
H1: In Cabbage [Cabbage]Cabbage = Goat /\ In Cabbage [Goat] \/ Cabbage <> Goat /\ In Cabbage [Wolf; Cabbage] /\ ~ In Cabbage [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Goat; Cabbage]
H0: In Cabbage [Goat; Cabbage]
H1: In Cabbage [Cabbage]Cabbage = Goat /\ In Cabbage [Goat] \/ Cabbage <> Goat /\ In Cabbage [Wolf; Cabbage] /\ ~ In Cabbage [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Goat; Cabbage]
H0: In Cabbage [Goat; Cabbage]
H1: In Cabbage [Cabbage]Cabbage <> Goat /\ In Cabbage [Wolf; Cabbage] /\ ~ In Cabbage [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Goat; Cabbage]
H0: In Cabbage [Goat; Cabbage]
H1: In Cabbage [Cabbage]Cabbage <> Goatr: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Goat; Cabbage]
H0: In Cabbage [Goat; Cabbage]
H1: In Cabbage [Cabbage]In Cabbage [Wolf; Cabbage] /\ ~ In Cabbage [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Goat; Cabbage]
H0: In Cabbage [Goat; Cabbage]
H1: In Cabbage [Cabbage]In Cabbage [Wolf; Cabbage] /\ ~ In Cabbage [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Goat; Cabbage]
H0: In Cabbage [Goat; Cabbage]
H1: In Cabbage [Cabbage]In Cabbage [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Goat; Cabbage]
H0: In Cabbage [Goat; Cabbage]
H1: In Cabbage [Cabbage]~ In Cabbage [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage r
H: In Cabbage [Wolf; Goat; Cabbage]
H0: In Cabbage [Goat; Cabbage]
H1: In Cabbage [Cabbage]~ In Cabbage [Goat]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] []r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rNoEats [Wolf; Cabbage]r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] [](* initial state: everyone on the left bank *) apply initial; repeat auto with local. Qed.r: list Object
Hw: In Wolf r
Hg: In Goat r
Hc: In Cabbage rRiverCrossing Right [Wolf; Goat; Cabbage] []
End SecondAttempt.
Conclusions and Issues
In the end, I was surprised that I was able to produce something that at least resembled a model and proof to the problem. I thought I’d need much more to even begin dealing with this puzzle, especially after failing to find an example solution.
But there are still some issues that I cannot address on my own, given my current knowledge.
- I’m not sure if there is another “hole” in my logic, as the first time everything fit into place but was wrong.
- The
RiverCrossing
predicate and the solution still seem overly complicated. I feel that they should be shorter and cleaner… - Both proofs are backwards. I’d like to somehow start from the initial state and build my proof towards the desired goal. I guess one way is to “reverse” the constructors in
RiverCrossing
and start from the initial state in the solution goal. But that seems wrong. - I still need to specify the initial left and right river banks on the steps that carry an object. I expected that I could use
eapply
oreauto
and let Coq infer those later, yet that didn’t work out. This is kinda annoying. - If I were to use bullets when building the proof steps, each new step would get nested deeper and deeper, making it harder to read. So I just separated them the way I did. I’d love to know how to structure proofs of this form in a more elegant way…
I shared this problem in the Coq Zulip chat asking for advice, but unfortunately, at the time of writing, no one has replied yet. Maybe someone will shed light on those issues someday, and I hope to learn enough to address them in the (distant) future…