Skip to content

Commit 660ed4e

Browse files
committed
Create zebra.py
1 parent 7e936f1 commit 660ed4e

1 file changed

Lines changed: 63 additions & 0 deletions

File tree

pycona/benchmarks/zebra.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import cpmpy as cp
2+
from cpmpy.transformations.normalize import toplevel_list
3+
from ..answering_queries.constraint_oracle import ConstraintOracle
4+
from ..problem_instance import ProblemInstance, absvar
5+
6+
7+
def construct_zebra_problem():
8+
"""
9+
:Description: The zebra puzzle is a well-known logic puzzle. Five houses, each of a different color, are occupied by men of
10+
different nationalities, with different pets, drinks and cigarettes. The puzzle is to find out who owns the zebra.
11+
The puzzle has 15 clues that help determine the solution.
12+
:return: a ProblemInstance object, along with a constraint-based oracle
13+
"""
14+
# Create a dictionary with the parameters
15+
parameters = {"grid_size": 5, "num_categories": 5}
16+
17+
# Variables
18+
# Flattened array with 25 elements, representing 5 elements for each of the 5 categories
19+
grid = cp.intvar(1, 5, shape=(5, 5), name="grid")
20+
21+
C_T = list()
22+
23+
# Extract variables for readability
24+
ukr, norge, eng, spain, jap = grid[0, :] # Nationalities
25+
red, blue, yellow, green, ivory = grid[1,:] # Colors
26+
oldGold, parly, kools, lucky, chest = grid[2,:] # Cigarettes
27+
zebra, dog, horse, fox, snails = grid[3,:] # Pets
28+
coffee, tea, h2o, milk, oj = grid[4,:] # Drinks
29+
30+
# Add all constraints
31+
C_T += [(eng == red)] # Englishman lives in the red house
32+
C_T += [(spain == dog)] # Spaniard owns the dog
33+
C_T += [(coffee == green)] # Coffee is drunk in the green house
34+
C_T += [(ukr == tea)] # Ukrainian drinks tea
35+
C_T += [(green == ivory + 1)] # Green house is immediately right of the ivory house
36+
C_T += [(oldGold == snails)] # OldGold smoker owns snails
37+
C_T += [(kools == yellow)] # Kools are smoked in the yellow house
38+
C_T += [(milk == 3)] # Milk is drunk in the middle house
39+
C_T += [(norge == 1)] # Norwegian lives in the first house
40+
C_T += [(abs(chest - fox) == 1)] # Chesterfield smoker lives next to the man with the fox
41+
C_T += [(abs(kools - horse) == 1)] # Kools are smoked in the house next to the house with the horse
42+
C_T += [(lucky == oj)] # Lucky smoker drinks orange juice
43+
C_T += [(jap == parly)] # Japanese smokes Parliaments
44+
C_T += [(abs(norge - blue) == 1)] # Norwegian lives next to the blue house
45+
46+
# Each row must have different values
47+
for row in grid:
48+
C_T += list(cp.AllDifferent(row).decompose())
49+
50+
# Create the language:
51+
AV = absvar(2) # create abstract vars - as many as maximum arity
52+
53+
# create abstract relations using the abstract vars
54+
lang = [AV[0] == AV[1], AV[0] != AV[1], AV[0] < AV[1], AV[0] > AV[1], AV[0] >= AV[1], AV[0] <= AV[1],
55+
abs(AV[0] - AV[1]) == 1, abs(AV[0] - AV[1]) != 1, AV[0] - AV[1] == 1, AV[1] - AV[0] == 1] + [AV[0] == constant for constant in range(1, 6)] + [AV[0] != constant for constant in range(1, 6)]
56+
57+
instance = ProblemInstance(variables=grid, params=parameters, language=lang, name="zebra")
58+
59+
oracle = ConstraintOracle(list(set(toplevel_list(C_T))))
60+
61+
62+
63+
return instance, oracle

0 commit comments

Comments
 (0)