如何解析 Clingo Python 中的程序部分?
How to parse program parts in Clingo Python?
我正在尝试 运行 python 中的以下 Blockworld 规划程序:
#include <incmode>.
#program base.
% Define
location(table).
location(X) :- block(X).
holds(F,0) :- init(F).
#program step(t).
% Generate
{ move(X,Y,t) : block(X), location(Y), X != Y } = 1.
% Test
:- move(X,Y,t), holds(on(A,X),t-1).
:- move(X,Y,t), holds(on(B,Y),t-1), B != X, Y != table.
% Define
moved(X,t) :- move(X,Y,t).
holds(on(X,Y),t) :- move(X,Y,t).
holds(on(X,Z),t) :- holds(on(X,Z),t-1), not moved(X,t).
#program check(t).
% Test
:- query(t), goal(F), not holds(F,t).
% Display
#show move/3.
#program base.
% Sussman Anomaly
%
block(b0).
block(b1).
block(b2).
%
% initial state:
%
% 2
% 0 1
% -------
%
init(on(b1,table)).
init(on(b2,b0)).
init(on(b0,table)).
%
% goal state:
%
% 2
% 1
% 0
% -------
%
goal(on(b1,b0)).
goal(on(b2,b1)).
goal(on(b0,table)).
我通过使用以下简单函数来做到这一点
def print_answer_sets(program):
control = clingo.Control()
control.add("base", [], program)
control.ground([("base", [])])
control.configuration.solve.models = 0
for model in control.solve(yield_=True):
sorted_model = [str(atom) for atom in model.symbols(shown=True)]
sorted_model.sort()
print("Answer set: {{{}}}".format(", ".join(sorted_model)))
我将上面程序的一个长三引号字符串传递给它。即
print_answer_sets("""
#include <incmode>.
#program base.
% Define
location(table).
location(X) :- bl
...etc.
""")
这通常适用于其他 clingo 程序。
但是,我似乎无法生成答案集,并且出现错误
no atoms over signature occur in program:
move/3
请注意,运行在终端或他们的 web interface 上使用 clingo 直接运行同一个程序可以正常工作。
我认为这是因为此字符串使用了多个“#program”语句和一个“#include”语句,我可能无法在 print_answer_sets
中正确(或根本)解析这些语句。有没有办法正确处理 python 中的程序部分?我试过查看文档和用户手册,但它有点密集。
谢谢!
我的教授帮助我找到了解决方案。我为自己和其他人添加了一些评论并在下面发布:
import clingo
asp_code_base = """
#include <incmode>.
% Define
location(table).
location(X) :- block(X).
holds(F,0) :- init(F).
block(b0).
block(b1).
block(b2).
init(on(b1,table)).
init(on(b2,b0)).
init(on(b0,table)).
goal(on(b1,b0)).
goal(on(b2,b1)).
goal(on(b0,table)).
#show move/3.
"""
asp_code_step = """
% Generate
{ move(X,Y,t) : block(X), location(Y), X != Y } = 1.
% Test
:- move(X,Y,t), holds(on(A,X),t-1).
:- move(X,Y,t), holds(on(B,Y),t-1), B != X, Y != table.
% Define
moved(X,t) :- move(X,Y,t).
holds(on(X,Y),t) :- move(X,Y,t).
holds(on(X,Z),t) :- holds(on(X,Z),t-1), not moved(X,t).
"""
asp_code_check = """
#external query(t).
% Test
:- query(t), goal(F), not holds(F,t).
"""
def on_model(model):
print("Found solution:", model)
# this is an arbitrary upper limit set to ensure process terminates
max_step = 5
control = clingo.Control()
control.configuration.solve.models = 1 # find one answer only
# add each #program
control.add("base", [], asp_code_base)
control.add("step", ["t"], asp_code_step)
control.add("check", ["t"], asp_code_check)
# for grounding, we make use of a parts array
parts = []
parts.append(("base", []))
control.ground(parts)
ret, step = None, 1
# try solving until max number of steps or until solved
while step <= max_step and (step == 1 or not ret.satisfiable):
parts = []
# handle #external call
control.release_external(clingo.Function("query", [clingo.Number(step - 1)]))
parts.append(("step", [clingo.Number(step)]))
parts.append(("check", [clingo.Number(step)]))
control.cleanup() # cleanup previous grounding call, so we can ground again
control.ground(parts)
# finish handling #external call
control.assign_external(clingo.Function("query", [clingo.Number(step)]), True)
print(f"Solving step: t={step}")
ret = control.solve(on_model=on_model)
print(f"Returned: {ret}")
step += 1
如预期的那样输出(省略警告)
Solving step: t=1
Returned: UNSAT
Solving step: t=2
Returned: UNSAT
Solving step: t=3
Found solution: move(b2,table,1) move(b1,b0,2) move(b2,b1,3)
Returned: SAT
我正在尝试 运行 python 中的以下 Blockworld 规划程序:
#include <incmode>.
#program base.
% Define
location(table).
location(X) :- block(X).
holds(F,0) :- init(F).
#program step(t).
% Generate
{ move(X,Y,t) : block(X), location(Y), X != Y } = 1.
% Test
:- move(X,Y,t), holds(on(A,X),t-1).
:- move(X,Y,t), holds(on(B,Y),t-1), B != X, Y != table.
% Define
moved(X,t) :- move(X,Y,t).
holds(on(X,Y),t) :- move(X,Y,t).
holds(on(X,Z),t) :- holds(on(X,Z),t-1), not moved(X,t).
#program check(t).
% Test
:- query(t), goal(F), not holds(F,t).
% Display
#show move/3.
#program base.
% Sussman Anomaly
%
block(b0).
block(b1).
block(b2).
%
% initial state:
%
% 2
% 0 1
% -------
%
init(on(b1,table)).
init(on(b2,b0)).
init(on(b0,table)).
%
% goal state:
%
% 2
% 1
% 0
% -------
%
goal(on(b1,b0)).
goal(on(b2,b1)).
goal(on(b0,table)).
我通过使用以下简单函数来做到这一点
def print_answer_sets(program):
control = clingo.Control()
control.add("base", [], program)
control.ground([("base", [])])
control.configuration.solve.models = 0
for model in control.solve(yield_=True):
sorted_model = [str(atom) for atom in model.symbols(shown=True)]
sorted_model.sort()
print("Answer set: {{{}}}".format(", ".join(sorted_model)))
我将上面程序的一个长三引号字符串传递给它。即
print_answer_sets("""
#include <incmode>.
#program base.
% Define
location(table).
location(X) :- bl
...etc.
""")
这通常适用于其他 clingo 程序。
但是,我似乎无法生成答案集,并且出现错误
no atoms over signature occur in program:
move/3
请注意,运行在终端或他们的 web interface 上使用 clingo 直接运行同一个程序可以正常工作。
我认为这是因为此字符串使用了多个“#program”语句和一个“#include”语句,我可能无法在 print_answer_sets
中正确(或根本)解析这些语句。有没有办法正确处理 python 中的程序部分?我试过查看文档和用户手册,但它有点密集。
谢谢!
我的教授帮助我找到了解决方案。我为自己和其他人添加了一些评论并在下面发布:
import clingo
asp_code_base = """
#include <incmode>.
% Define
location(table).
location(X) :- block(X).
holds(F,0) :- init(F).
block(b0).
block(b1).
block(b2).
init(on(b1,table)).
init(on(b2,b0)).
init(on(b0,table)).
goal(on(b1,b0)).
goal(on(b2,b1)).
goal(on(b0,table)).
#show move/3.
"""
asp_code_step = """
% Generate
{ move(X,Y,t) : block(X), location(Y), X != Y } = 1.
% Test
:- move(X,Y,t), holds(on(A,X),t-1).
:- move(X,Y,t), holds(on(B,Y),t-1), B != X, Y != table.
% Define
moved(X,t) :- move(X,Y,t).
holds(on(X,Y),t) :- move(X,Y,t).
holds(on(X,Z),t) :- holds(on(X,Z),t-1), not moved(X,t).
"""
asp_code_check = """
#external query(t).
% Test
:- query(t), goal(F), not holds(F,t).
"""
def on_model(model):
print("Found solution:", model)
# this is an arbitrary upper limit set to ensure process terminates
max_step = 5
control = clingo.Control()
control.configuration.solve.models = 1 # find one answer only
# add each #program
control.add("base", [], asp_code_base)
control.add("step", ["t"], asp_code_step)
control.add("check", ["t"], asp_code_check)
# for grounding, we make use of a parts array
parts = []
parts.append(("base", []))
control.ground(parts)
ret, step = None, 1
# try solving until max number of steps or until solved
while step <= max_step and (step == 1 or not ret.satisfiable):
parts = []
# handle #external call
control.release_external(clingo.Function("query", [clingo.Number(step - 1)]))
parts.append(("step", [clingo.Number(step)]))
parts.append(("check", [clingo.Number(step)]))
control.cleanup() # cleanup previous grounding call, so we can ground again
control.ground(parts)
# finish handling #external call
control.assign_external(clingo.Function("query", [clingo.Number(step)]), True)
print(f"Solving step: t={step}")
ret = control.solve(on_model=on_model)
print(f"Returned: {ret}")
step += 1
如预期的那样输出(省略警告)
Solving step: t=1
Returned: UNSAT
Solving step: t=2
Returned: UNSAT
Solving step: t=3
Found solution: move(b2,table,1) move(b1,b0,2) move(b2,b1,3)
Returned: SAT