This engine can solve logic puzzles with 1:1 correspondances between discrete sets of equal size and unique elements.
[taken from Question 1 of the KIT University Computer Science Self Assessment Test, translated from german]
The three friends Anne, Anja and Anke visit the courses software technic, algorythms and programming paradigms with varying degrees of success (1.7/2.6/3.8). (note: in Germany the grading system is from 1 (best) to 6 (worst)) They search for their results in a list under the names Becker, Kramer and Wolff.
- Anne passed with a grade of 2.6.
- Anja took the course algorythms. She has a better grade than student Wolff.
- Anke did not take programming paradigms.
from solver import Model
from sets import Set, OrderedSet
names = Set('names', ['anne', 'anja', 'anke'])
last_names = Set('last_names', ['becker', 'kramer', 'wolff'])
subjects = Set('subjects', ['software', 'algorythms', 'paradigms'])
grades = OrderedSet('grades', [1.7, 2.6, 3.8])
model = Model(names, last_names, subjects, grades)
# == 1 ==
# read: `the grade of anne is 2.6` / `the grade related to the name anne is 2.6`
model.relate(names['anne'](grades) == 2.6)
# which is the same as:
# model.relate(names['anne'] == grades[2.6])
# == 2 ==
model.relate(names['anja'] == subjects['algorythms'])
model.relate(names['anja'](grades) < last_names['wolff'](grades))
# == 3 ==
model.relate(names['anke'] != subjects['paradigms'])
model.relate((names['anke'] & last_names['kramer']) > grades[1.7])
# the `&` above is a short form for the 2 following relations:
# model.relate(names['anke'] > grades[1.7])
# model.relate(last_names['kramer'] > grades[1.7])
# We can deduce that anke is not named kramer, but the machine cannot since it does not know how names work.
# This is why we must specify this additional constraint.
model.relate(names['anke'] != last_names['kramer'])
solver = model.solver()
# a `ValueError` is thrown if there are not enough constraints to solve the model fully
# or the model ran for too few iterations (unlikey for small models).
# Check whether oyur input text allows you to deduce another formal statement whcih you didnt notice before.
# If there is a sttement error, aka no element from a set satisfies the conditions,
# a `ArithemeticError` is thrown. This should be due to an input error by the user.
try:
solution = solver.solve()
print(solution)
except ValueError:
print(solver)
names | last_names | subjects | grades |
---|---|---|---|
anne | kramer | paradigms | 2.6 |
anja | becker | algorythms | 1.7 |
anke | wolff | software | 3.8 |