Такие проблемы, безусловно, решаются с помощью Z3 и любого SMT-решателя в целом. Но вы не получите приятных возможностей выделенной системы по понятным причинам. Кодирование может быть более многословным, и, как вы узнали, модели интерпретации могут быть довольно хитрыми.
Я думаю, что ваше кодирование - хорошее начало, но вам будет лучше, если сделать Block
перечислимой сортировкой и объявить блоки в вашей системе явно. Это сделает кодирование намного ближе к тому, как обычно кодируются системы планирования, а также поможет интерпретировать сами модели.
Исходя из этого, вот как я go расскажу о кодировании вашей проблемы, предполагая, что мы жить во вселенной с тремя блоками с именами A
, B
и C
:
from z3 import *
Block, (A, B, C) = EnumSort('Block', ('A', 'B', 'C'))
On = Function ("On", Block, Block, BoolSort())
Above = Function ("Above", Block, Block, BoolSort())
objects = [A, B, C]
solver = Solver()
solver.add(And(On(A, B), On(B, C)))
x, y, z = Consts ("x y z", Block)
solver.add(ForAll([x, y], Implies(On(x, y), Above(x, y))))
solver.add(ForAll([x, y, z], Implies(And(On(x, z), Above(z, y)), Above(x, y))))
solver.add(ForAll([x], Not(On(x, x))))
solver.add(ForAll([x], Not(Above(x, x))))
if solver.check() == sat:
print "sat"
m = solver.model()
for i in objects:
for j in objects:
if m.evaluate(On(i, j)):
print "On(%s, %s)" % (i, j)
if m.evaluate(Above(i, j)):
print "Above(%s, %s)" % (i, j)
else:
print "unsat"
(Обратите внимание, что мне пришлось настроить ваш P2
, который выглядел не совсем правильно. Я также добавил две аксиомы, говоря, что On
и Above
нерефлексивны. Но вы можете изменить и поиграть с различными аксиомами и посмотреть, какие модели вы получаете.)
Для этого ввода z3 говорит:
sat
On(A, B)
Above(A, B)
Above(A, C)
On(B, C)
Above(B, C)
, который является допустимым сценарием, удовлетворяющим всем ограничениям.
Я должен отметить, что решатели SMT обычно не способны к количественным рассуждениям. Но, сохраняя Вселенную конечной (и маленькой!), Они могут довольно хорошо справиться с любым количеством таких аксиом. Если вы представите объекты из бесконечной области, такие как Int
, Real
и др. c., Вещи станут более интересными и, возможно, слишком сложными для z3. Но вам не нужно такое причудливое кодирование для классовых c проблем с блоком / планированием.
Надеюсь, это поможет вам начать!