0

我现在正在学习 prolog 并尝试使用 cligo 来建模关键约束,但遇到了一些麻烦,希望有人能帮帮我。这是我的问题:

  1. 我想建立一个关键约束并在 cligo 中编写如下内容
:-stu(X,Y1,Y2),stu(X,Z1,Z2),not(Y1=Z1,Y2=Z2).

作为完整性约束,但出现语法错误。我尝试了另一种方式,它似乎工作。

Y1=Z1:-stu(X,Y1,Y2),stu(X,Z1,Z2).
Y2=Z2:-stu(X,Y1,Y2),stu(X,Z1,Z2).

但是我仍然想知道是否可以将单独的约束组合成一个关键约束,从而使程序更简洁?

  1. 另一个问题是关于如何在 cligo 中建立“存在某些东西”的事实,我想要实现的是使用 cligo 来判断两组给定的规则是否可以满足,这里是一个例子。

第一组规则说“存在一个 id 为 1 名称为 mike 的学生”:

在此处输入图像描述

和“具有相同 id 的两个学生应该具有相同的姓名和年龄”(这是一个关键约束):

在此处输入图像描述

所以我在 Clingo 中写了第一组规则:

stu(1,"mike",v).
:-stu(X,Y1,Y2),stu(X,Z1,Z2),(Y1,Y2)!=(Z1,Z2).

假设给定第二组规则,即“存在一个 id 为 1 且年龄为 27 的学生”:

在此处输入图像描述

第二组规则用 Clingo 写成:

stu(1,v,27).

我的问题是,如果简单地将这两组规则放在一个程序中,Clingo 会判断它们不能满足原因 ("mike",v) != (v, 27)。所以我的解决方案肯定有问题(可能是建立存在的方式),因为如果你有一个 id = 1、name = "mike" 和 age = 27 的学生,这两组规则实际上是可以满足的。我想知道如果有办法使用 Clingo 来判断上述两组规则的可满足性,谢谢!

4

1 回答 1

1

如果要使用元组比较发布完整性约束

:-stu(X,Y1,Y2),stu(X,Z1,Z2), (Y1,Z2)!=(Z1,Z2).

可能是你想写的。

像这样的规则

Y1=Z1:-stu(X,Y1,Y2),stu(X,Z1,Z2).

相当于

:-stu(X,Y1,Y2),stu(X,Z1,Z2), Y1!=Z1.

回答你的第二个问题:

将年龄和姓名分成两个谓词。您引入了一个任意的“v”作为“未给出”的占位符,这是您出现问题的原因。你的问题都不存在,如果可能没有名字或年龄,它的风格也会更简洁。

stu_name(123,"steve").
stu_age(123,42).
% it is not possible to have the same ID but different names
:- stu_name(ID,Name1), stu_name(ID,Name2), Name1 != Name2.
% it is not possible to have the same ID but different ages
:- stu_age(ID,Age1), stu_age(ID,Age2), Age1 != Age2.

分开姓名和年龄允许您没有两个条目之一。当您使用三元 stu(ID,Name,Age) 谓词时,您实际上总是必须给出名称 AND 和年龄(“v”不是什么神奇的东西,它会被解释为姓名或年龄)

为避免多个学生具有相同的 id,您可以编写:

stu(123,"Anne",30).
stu(123,"Mia",14).
% it is not possible to have the same ID but not completely equal entries
:- stu(ID,Name1,Age1), stu(ID,Name2,Age2), (Name1,Age1)!=(Name2,Age2).
于 2021-04-12T09:33:57.150 回答