Prolog 字典谓词匹配
Prolog dict predicate matching
鉴于此程序,为什么我必须在谓词中定义每个原子,即使它们是匿名的。为什么字典谓词中未定义的变量不被认为是匿名的?
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!').
^顺便说一句,那不匹配。
如果我必须在字典中定义每个可能的值以使用字典,我也可能只使用一个结构。
这里的动机是什么?我可以做些什么来使我的谓词简洁吗?我正在尝试定义一个包含 30 个变量的字典,这是一个巨大的障碍。如果我被迫定义每个变量(匿名或非匿名),它将大大增加我的程序大小。
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}).
和查询
matchByX(1, P).
将return:
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}.
通过执行以下操作,我能够完成所需的工作
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
鉴于此程序,为什么我必须在谓词中定义每个原子,即使它们是匿名的。为什么字典谓词中未定义的变量不被认为是匿名的?
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!').
^顺便说一句,那不匹配。
如果我必须在字典中定义每个可能的值以使用字典,我也可能只使用一个结构。
这里的动机是什么?我可以做些什么来使我的谓词简洁吗?我正在尝试定义一个包含 30 个变量的字典,这是一个巨大的障碍。如果我被迫定义每个变量(匿名或非匿名),它将大大增加我的程序大小。
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}).
和查询
matchByX(1, P).
将return:
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}.
通过执行以下操作,我能够完成所需的工作
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