计算Prolog中特定对象元素的数目
我的代码可以很好地处理数字,但不能处理对象类型计算Prolog中特定对象元素的数目,prolog,Prolog,我的代码可以很好地处理数字,但不能处理对象类型 计数(u,[],0)。 计数(字段[Field | Tail],N):- 计数(字段、尾部、N1), N是N1+1。 计数(字段[H|Tail],N):- 字段\=H, 计数(字段、尾部、N)。 ?-计数(1[1,2,3],X)。 X=1.%好啊 -计数(1,[1,2,3,1],X)。 X=2.%好啊 -计数(元素(温度,u),[元素(温度,值1),元素(温度,值2)],X)。 X=1.%我以为这里有两个。 对于最后一行,我期望X=2,因为
计数(u,[],0)。
计数(字段[Field | Tail],N):-
计数(字段、尾部、N1),
N是N1+1。
计数(字段[H|Tail],N):-
字段\=H,
计数(字段、尾部、N)。
?-计数(1[1,2,3],X)。
X=1.%好啊
-计数(1,[1,2,3,1],X)。
X=2.%好啊
-计数(元素(温度,u),[元素(温度,值1),元素(温度,值2)],X)。
X=1.%我以为这里有两个。
对于最后一行,我期望X=2
,因为
elem(temp,u)=elem(temp,val1)
elem(temp,u)=elem(temp,val2)
- 问题1。为什么它不起作用
- 问题2。我怎样才能使它适用于任何类型
谢谢。您的代码不起作用,因为
elem(temp,)
与列表的第一项统一,并且统一在递归调用中传播。您可以通过跟踪执行来观察这一点
?- trace, count(elem(temp, _), [elem(temp, val1), elem(temp, val2)], X).
Call: (11) count(elem(temp, _30894), [elem(temp, val1), elem(temp, val2)], _30926) ? creep
Call: (12) count(elem(temp, val1), [elem(temp, val2)], _31518) ? creep
Call: (13) elem(temp, val1)\=elem(temp, val2) ? creep
Exit: (13) elem(temp, val1)\=elem(temp, val2) ? creep
Call: (13) count(elem(temp, val1), [], _31650) ? creep
Exit: (13) count(elem(temp, val1), [], 0) ? creep
Exit: (12) count(elem(temp, val1), [elem(temp, val2)], 0) ? creep
Call: (12) _30926 is 0+1 ? creep
Exit: (12) 1 is 0+1 ? creep
Exit: (11) count(elem(temp, val1), [elem(temp, val1), elem(temp, val2)], 1) ? creep
X = 1 .
要使其工作,可以使用谓词:
因此,一种可能的解决办法是:
count(_, [], 0).
count(Field, [First|Tail], N) :-
subsumes_term(Field, First),
count(Field, Tail, N1),
N is N1 + 1.
count(Field, [First|Tail], N) :-
not(subsumes_term(Field, First)),
count(Field, Tail, N).
运行示例:
?- count(1, [1,2,3], X).
X = 1 ;
false.
?- count(1, [1,2,3,1], X).
X = 2 ;
false.
?- count(elem(temp, _), [elem(temp, val1), elem(temp, val2)], X).
X = 2 ;
false.
效率更高的版本是:
count(Field, List, Count) :-
count(List, Field, 0, Count).
count([], _, Acc, Acc).
count([First|Tail], Field, Acc, Count) :-
( subsumes_term(Field, First)
-> Acc1 is Acc + 1
; Acc1 is Acc ),
count(Tail, Field, Acc1, Count).
A1。它不起作用,因为
\uu
被映射到单个值(\uu=val1
)。一旦映射了val1
,val2
就不再匹配了。谢谢!我意识到它为什么不起作用,但却找不到一种方法使它起作用。这太神奇了。
count(Field, List, Count) :-
count(List, Field, 0, Count).
count([], _, Acc, Acc).
count([First|Tail], Field, Acc, Count) :-
( subsumes_term(Field, First)
-> Acc1 is Acc + 1
; Acc1 is Acc ),
count(Tail, Field, Acc1, Count).