Prolog dict谓词匹配

时间:2015-03-23 13:57:25

标签: prolog predicates

鉴于这个程序,为什么我被迫定义谓词中的每个原子,即使它们是匿名的。为什么dict谓词中未定义的变量不被认为是匿名的?

funt2(X) :-
    X = point{x:5, y:6}.

evalfunt(point{x:5, y : 6}) :-
    write('hello world!').

evalfunt(point{x:_, y : _} ) :-
    write('GoodBye world!').

为什么我不能说

evalfunt(point{x:5}) :-
        write('GoodBye world!').
顺便说一句,

^不会匹配。

如果我必须在dict中定义每个可能的值来使用dicts,我也可以使用一个结构。

这里的动机是什么?我能做些什么来使我的谓词简洁吗?我试图用30个变量来定义一个dict,这是一个巨大的障碍。如果我被迫定义每个变量(匿名或不是匿名),它会增加我的程序大小。

2 个答案:

答案 0 :(得分:4)

Dict只是一种复杂的数据类型,如元组,它具有数据和结构。如果你有,例如两个事实:

fact(point{x:5, y:6}).
fact(point{x:5}).

然后查询

fact(point{x:_}).

将匹配第二个,但不匹配第一个。 和查询

fact(point{x:_, y:_}).

将匹配第一个,但不匹配第二个。

现在,如果您只想通过一个特定字段匹配fact(point{x:_, y:_, z:_})形式的事实,您可以随时编写帮助规则:

matchByX(X, P) :- fact(P), P=point{x:X, y:_, z:_}. 

所以有事实:

fact(point{x:5, y:6, z:1}).
fact(point{x:1, y:2, z:3}).
fact(point{x:2, y:65, z:4}).

和quering

matchByX(1, P).

将返回:

P = point{x:1, y:2, z:3}


更新:
此外,在SWI-Prolog 7版本中,字段名称也可以匹配,因此它可以以更通用的方式编写,即使对于具有不同结构的事实:

fact(point{x:5, y:6, z:1}).
fact(point{x:1, y:2}).
fact(point{x:2}).
fact(point{x:2, y:2}).

matchByField(F, X, P) :- fact(P), P.F = X.

所以查询:

?- matchByField(x, 2, P).
P = point{x:2} ;
P = point{x:2, y:2}.

答案 1 :(得分:2)

我通过以下方式完成了我所需要的工作

checkiffive(Y) :- 
        get_dict(x, Y, V), V=5.

您需要使用内置方法来统一字典中的值。

SWI序言参考的第5.4章描述

http://www.swi-prolog.org/download/devel/doc/SWI-Prolog-7.1.16.pdf