如何在答案集编程中对此进行编码?

问题描述

我绝对是回答集合编程的新手,而我一直在努力解决一个非常简单的问题。该程序需要用clingo编写。

所以这是问题:

抽象论证框架由一组参数A组成 以及它们之间的攻击关系R⊆A XA。对于任何两个参数 a1和a2,如果(a1,a2)∈R,那么我们说a1攻击a2:如果一个 接受参数a1,然后对参数a2产生怀疑。正式地, 如果满足以下两个条件,则参数E⊆A的子集稳定 按住:

  1. E中没有论点会攻击E的任何其他论点。
  2. E之外的任何论点都受到E的论点的攻击。

编写一个ASP程序,该程序标识一个变量中稳定的参数子集。 通过答案给出实例。该实例将通过提供 与A和R对应的两个谓词参数/ 1和Attack / 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).

我根本不知道该如何处理。

请帮助。

解决方法

以下是一种简单的三步解决方法:

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

所以从2开始:

产生可能的结果。简单地说一下:无论是否选择每个参数。
可能部分可以用{}求和。

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

或更简单:我从参数中选择一个求和

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

让我们使用共振模式#show choose/1.的{​​{3}}和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),choose(Y).
:- argument(X),X)} 0.

#show choose/1.