关于答案集编程的新手问题

Newbie questions on Answer Set Programming

我对 Clingo(和逻辑编程)完全陌生,我正在寻找最佳方法来实现以下基本约束:

Q1。我有一个谓词 selected(T),其中 T 的范围从 1 到 N=5;我如何指定 存在至少一个 T 使得 selected(T) ?

Q2。我有一个二进制谓词 wrap(E,T),其中 E、T 的范围从 1 到 M、N;我如何指定 对于每个 E 至少存在一个 T 这样 wrap(E,T) ?

Q3。我如何指定 if selected(a) OR selected(b) then selected(c) must be false

我实际上使用了两行代码,但可能有更好的方法:

  :- selected(c), selected(a) .
  :- selected(c), selected(b) .

Q4。如何指定如果某个条件 C(A) 为真,则两个一元谓词 p1(A) 和 p2(A) 必须具有相同的值?

我其实用了两行代码:

p1(A) :- C(A), p2(A)
      :- C(A), not p2(A), p1(A)

Q5。您推荐哪本书来很好地介绍答案集编程?

Q1:

%%%% Config
#const n = 5.
%%%% Code
% selected is not an empty predicate
1 { selected(1..n) }.

Q2:

%%%% Config
%% N
#const n = 5.
%% M
#const m = 4.

%%%% Helpers
%% Ts
t(1..n).
%% Es
e(1..m).

%%%% Code
% there is an E, then there must be at least one
% wrap(E,T) where T is from t
1 { wrap(E, T) : t(T) } :- e(E).

Q3:

:- selected(c), selected(a;b).

Q4:其实我是这么想的

:- c(A), p1(A)!=p2(A).

可以,但显然不行。我认为最清晰的写法是

:- c(A), not p1(A), p2(A).
:- c(A), p1(A), not p2(A).

虽然我对 'not' 的使用不满意。也许最近用过 ASP 的人记得一个更好的解决方案。或者,您可以将 p1 和 p2 扩展为二进制谓词并编写

:- c(A), p1(A,P1), p2(A,P2), P1!=P2.

Q5:很遗憾,在我看来,ASP 没有 的书。也就是说,我读过的绝对最好的是 "Answer Set Solving in Practice",作者通常是 Gebser、Kaminski、Kaufmann 和 Schaub。在阅读与 potassco 系列相关的材料时,您需要在 gringo 3 和 gringo 4 语言差异之间进行调整,官方手册对此解释得不好,我看到的任何其他资源也没有。

编辑:现在 Potassco 工具有一本新手册,其中包含 clasp 3 和 gringo/clingo 4.5 的最新语法,可在此处找到:http://sourceforge.net/projects/potassco/files/guide/2.0/