Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

River crossing puzzle in z3

Tags:

z3

z3py

I've just start learning z3 solver. I've seen some puzzles solved by z3 i.e sudoku and Eight Queens. I'm just wondering if any one solved River crossing problem in z3. z3 seems very good in problem solving.

Regards

like image 357
Moody Avatar asked Mar 19 '23 02:03

Moody


1 Answers

I tried to model it and I came up with the following. You can run it in the interactive rise4fun environment and see the answer:

(declare-datatypes () ((Object Human Fox Rabbit Cabbage)))
(declare-datatypes () ((Location Left Right OnBoat)))
(declare-const n Int)
(declare-fun objectLocation (Int Object) Location)

(assert (= n 14))

(assert (forall ((x Object) (t Int)) (=> (= t 0) (= (objectLocation t x) Left))))
(assert (forall ((x Object) (t Int)) (=> (= t n) (= (objectLocation t x) Right))))
(assert
  (forall
    ((t Int))
    (=>
      (and (>= t 0) (<= t n))
      (<=
        (+
          (ite (= (objectLocation t Human) OnBoat) 1 0)
          (ite (= (objectLocation t Fox) OnBoat) 1 0)
          (ite (= (objectLocation t Rabbit) OnBoat) 1 0)
          (ite (= (objectLocation t Cabbage) OnBoat) 1 0)
        )
        2
      )
    )
  )
)
(assert
  (forall
    ((x Object) (t Int))
    (=>
      (and (>= t 1) (<= t (- n 1)))
      (iff
        (= (objectLocation t x) OnBoat)
        (and
          (not (= (objectLocation (+ t 1) x) OnBoat))
          (not (= (objectLocation (- t 1) x) OnBoat))
          (not (= (objectLocation (+ t 1) x) (objectLocation (- t 1) x)))
        )
      )
    )
  )
)
(assert
  (forall
    ((x Object) (t Int))
    (=>
      (and (>= t 1) (<= t n))
      (=>
        (not (= (objectLocation t x) (objectLocation (- t 1) x)))
        (or
          (= (objectLocation t x) OnBoat)
          (= (objectLocation (- t 1) x) OnBoat)
        )
      )
    )
  )
)
(assert
  (forall
    ((x Object) (y Object) (t Int))
    (=>
      (and (>= t 1) (<= t n))
      (=>
        (and (= (objectLocation t x) OnBoat) (= (objectLocation t y) OnBoat))
        (= (objectLocation (- t 1) x) (objectLocation (- t 1) y))
      )
    )
  )
)
(assert
  (forall
    ((x Object) (t Int))
    (=>
      (and (>= t 0) (<= t n))
      (=>
        (= (objectLocation t x) OnBoat)
        (= (objectLocation t Human) OnBoat)
      )
    )
  )
)
(assert
  (forall
    ((t Int))
    (=>
      (and (>= t 0) (<= t n))
      (=>
        (= (objectLocation t Fox) (objectLocation t Rabbit))
        (= (objectLocation t Human) (objectLocation t Rabbit))
      )
    )
  )
)
(assert
  (forall
    ((t Int))
    (=>
      (and (>= t 0) (<= t n))
      (=>
        (= (objectLocation t Cabbage) (objectLocation t Rabbit))
        (= (objectLocation t Human) (objectLocation t Rabbit))
      )
    )
  )
)

(check-sat)

(echo "step 0")
(eval (objectLocation 0 Human))
(eval (objectLocation 0 Fox))
(eval (objectLocation 0 Rabbit))
(eval (objectLocation 0 Cabbage))

(echo "step 1")
(eval (objectLocation 1 Human))
(eval (objectLocation 1 Fox))
(eval (objectLocation 1 Rabbit))
(eval (objectLocation 1 Cabbage))

(echo "step 2")
(eval (objectLocation 2 Human))
(eval (objectLocation 2 Fox))
(eval (objectLocation 2 Rabbit))
(eval (objectLocation 2 Cabbage))

(echo "step 3")
(eval (objectLocation 3 Human))
(eval (objectLocation 3 Fox))
(eval (objectLocation 3 Rabbit))
(eval (objectLocation 3 Cabbage))

(echo "step 4")
(eval (objectLocation 4 Human))
(eval (objectLocation 4 Fox))
(eval (objectLocation 4 Rabbit))
(eval (objectLocation 4 Cabbage))

(echo "step 5")
(eval (objectLocation 5 Human))
(eval (objectLocation 5 Fox))
(eval (objectLocation 5 Rabbit))
(eval (objectLocation 5 Cabbage))

(echo "step 6")
(eval (objectLocation 6 Human))
(eval (objectLocation 6 Fox))
(eval (objectLocation 6 Rabbit))
(eval (objectLocation 6 Cabbage))

(echo "step 7")
(eval (objectLocation 7 Human))
(eval (objectLocation 7 Fox))
(eval (objectLocation 7 Rabbit))
(eval (objectLocation 7 Cabbage))

(echo "step 8")
(eval (objectLocation 8 Human))
(eval (objectLocation 8 Fox))
(eval (objectLocation 8 Rabbit))
(eval (objectLocation 8 Cabbage))

(echo "step 9")
(eval (objectLocation 9 Human))
(eval (objectLocation 9 Fox))
(eval (objectLocation 9 Rabbit))
(eval (objectLocation 9 Cabbage))

(echo "step 10")
(eval (objectLocation 10 Human))
(eval (objectLocation 10 Fox))
(eval (objectLocation 10 Rabbit))
(eval (objectLocation 10 Cabbage))

(echo "step 11")
(eval (objectLocation 11 Human))
(eval (objectLocation 11 Fox))
(eval (objectLocation 11 Rabbit))
(eval (objectLocation 11 Cabbage))

(echo "step 12")
(eval (objectLocation 12 Human))
(eval (objectLocation 12 Fox))
(eval (objectLocation 12 Rabbit))
(eval (objectLocation 12 Cabbage))

(echo "step 13")
(eval (objectLocation 13 Human))
(eval (objectLocation 13 Fox))
(eval (objectLocation 13 Rabbit))
(eval (objectLocation 13 Cabbage))

(echo "step 14")
(eval (objectLocation 14 Human))
(eval (objectLocation 14 Fox))
(eval (objectLocation 14 Rabbit))
(eval (objectLocation 14 Cabbage))

You can also run "(get-model)" to see a definition of the function "objectLocation" but I warn you that it will be very unintelligible.

Here is a short description of what is asserted:

  1. There can be at most 14 steps.
  2. At step 0, all objects are on the left.
  3. At step n, all objects should be on the right.
  4. At each step, there can be at most two objects in the boat.
  5. An object is on the boat at step t if and only if it is on different sides of the river at steps t-1 and t+1.
  6. If an object changes location from step t-1 to step t then one of these locations should be the boat.
  7. If two objects are on the boat at step t they should have been on the same side of the river at step t-1.
  8. If something is on the boat then the human should also be on the boat.
  9. If fox and rabbit are in the same location then human should also be there.
  10. If rabbit and cabbage are in the same location then human should also be there.
like image 165
Shahab Avatar answered May 16 '23 06:05

Shahab