在Prolog中,我如何能够删除多余的答案

时间:2014-10-22 06:13:47

标签: prolog backtracking non-repetitive

我正在使用prolog开发类似字典的程序,我的代码是这样的:

define(car,vehicle).
define(car,that).
define(car,has).
define(car,four).
define(car,wheels).
define(wheels,round).
define(wheels,object).
define(wheels,used).
define(wheels,in).
define(wheels,transportation).


defined(X):-define(X,_).

anotherdefined(X):- \+ undefined(X).
undefined(X):- \+define(X,_).        

我正在尝试编写一个定义的/ 1谓词,它会给我:

?-defined(X).
X = car ;
X = wheels ;
false.

然而,我的定义/ 1在每次反击X=car.时给我define(car,_).五次(自然) 而我的anotherdefined / 1只给我true.什么方法可以阻止prolog回溯到define(car,_).的其他实例,并跳到define(wheels,_).

编辑:我已经写了以下几行来获得我想要的结果,用givedefinedword / 1,

listdefined(X):-findall(Y,defined(Y),Z),sort(Z,X).
givedefinedword(X):-listdefined(List),member(X,List).

然而,因为我想要一个有效的谓词(我将在许多其他人中使用),它胜过了目的。这个谓词做了太多的过程。

或者,使用修改代码的谓词会更好吗? say准备已定义单词的列表,并在添加新定义时对其进行修改。

感谢。

2 个答案:

答案 0 :(得分:0)

如果您更改define以关联项目和列表,例如

definelist(car, [vehicle, that, has, four, wheels]).
% etc.
defined(X) :- definelist(X, _).

然后defined将不再产生重复,也不需要线性空间。

当然,现在必须以define(X, Y)执行查询definelist(X, L), member(Y, L)。如果您希望这也有效,您可能需要复制所有定义。

答案 1 :(得分:0)

你想用你的程序实现什么目标?您似乎希望获得以下形式的事实:

"汽车是一种有四个车轮的车辆"

"轮子是用于运输的圆形物体" (有点模糊)

你打算如何使用这些事实? @larsmans建议如果完全没问题,如果你想把你的陈述作为"句子"。这实际上取决于你对信息的处理方式。

考虑在数据库中构建信息:

is(car, vehicle).
is(bicycle, vehicle).
is(boat, vehicle).
has(car, wheel(four)).
has(car, motor).
has(bicycle, wheel(two)).

鉴于这个数据库,你至少可以问一个问题,"那里有什么车辆?","自行车有电机吗?"或者可能,& #34;汽车有多少轮子?"或者#34;哪些车辆没有轮子?"

?- is(X, vehicle).
?- has(bicycle, motor).
?- has(car, wheel(N)).
?- is(X, vehicle), \+ has(X, wheel(_)).

等等。

一旦更好地定义了问题,就可以更好地定义数据结构,这将使编写程序更容易解决问题。