1

我是一个回答集合编程的新手,我正在努力解决一个相当简单的问题。该程序需要用 cligo 编写。

所以这是一个问题:

一个抽象的论证框架由一组参数 A 和它们之间的攻击关系 R ⊆ AXA 组成。对于任意两个参数 a1 和 a2,如果 (a1, a2) ∈ R,那么我们说 a1 攻击 a2:如果一个人承认参数 a1,那么它就会对参数 a2 产生怀疑。形式上,如果满足以下两个条件,则参数 E ⊆ A 的子集是稳定的:

  1. E 中的任何论点都不会攻击 E 的任何其他论点。
  2. E 之外的任何参数都会受到来自 E 的参数的攻击。

编写一个 ASP 程序,通过答案集识别给定实例中参数的稳定子集。该实例将通过分别对应于 A 和 R 的两个谓词参数/1 和攻击/2 提供。

这是一个例子:

argument (a).    
argument (b).    
argument (c).    
argument (d).    
attack (a,b).    
attack (b,c).    
attack (d,c).

有效输出:

choose (a) choose (d)

这是我尝试过的,这显然是错误的:

choose(X)  :- argument(X), attack(X,Y).

我根本不知道如何处理这个问题。

请帮忙。

4

1 回答 1

1

一个简单的 3 步求解方法如下:

  1. 描述事实(检查)
  2. 结果生成你想要的,但让程序有选择
  3. 给出不适用的解决方案的规则

所以从2开始:

产生可能的结果。用简单的话想一想:对于每一个论点,我选择或不选择。可能或可能不是部分可以用 subsum
解决。{}

{choose(X)} :- argument(X).

甚至更简单:我从参数中选择一个子项

{choose(X):argument(X)}. 

让我们用Potassco#show choose/1.共振模式检查解决方案enumerate all

Answer: 1

Answer: 2
choose(b)
Answer: 3
choose(c).
..
Answer: 15
choose(a) choose(b) choose(c)
Answer: 16
choose(a) choose(b) choose(c) choose(d)
SATISFIABLE

找到所有组合。是时候删除错误的东西了。再说一遍:用简单的话想一想:我不可能选择两个论点来攻击另一个论点。(如果头部保持打开状态,则读取为 False。)

:- choose(X), attack(X,Y), choose(Y).

现在再次检查:

Answer: 1

Answer: 2
choose(a)
Answer: 3
choose(d)
Answer: 4
choose(a) choose(d)
Answer: 5
choose(c)
Answer: 6
choose(a) choose(c)
Answer: 7
choose(b)
Answer: 8
choose(b) choose(d)
SATISFIABLE

现在我们需要确保每个未选择的参数都受到至少一个选择的元素的攻击:

1 {choose(Y):attack(Y,X)} :- argument(X), not choose(X).

读取:对于每个X未选择的参数,攻击它的已选择参数的数量至少为一个。

让我们检查一下:

Answer: 1
choose(a) choose(d)
SATISFIABLE

好的。

由于约束通常是用空头来制定的,让我们重新制定最后一条规则:

:- argument(X), not choose(X), {choose(Y):attack(Y,X)} 0.

读取:没有参数X,没有被选择,并且有最多 0 个选择的参数,它攻击X它提供相同的输出。

完整代码:

argument (a;b;c;d).   
attack (a,b).    
attack (b,c).    
attack (d,c).

{choose(X):argument(X)}.
:- choose(X), attack(X,Y), choose(Y).
:- argument(X), not choose(X), {choose(Y):attack(Y,X)} 0.

#show choose/1.
于 2020-11-07T10:25:11.943 回答