我是初学者。我想实现一个名为high / 3的预测。此预测支持两种情况:一种是返回列表列表中一个字符的索引,例如:
high([[a,b,c],[d,e,f], [g,h]], b, X) returns X = 1
high([[a,b,c],[d,e,f], [g,h]], f, X) returns X = 2
第二种情况是,如果您提供索引,它还应返回该索引位置的所有字符。
e.g。
high([[a,b,c],[d,e,f], [g,h]], X, 1) returns X = b; X= e; X= h
high([[a,b,c],[d,e,f], [g,h]], X, 2) returns X = c; X= f.
我写了以下预告:
high([[X|_]|L], X, 0).
high([[Head|Tail]|L], X, H):- member(X, Tail), high([Tail|L], X, H1),H is H1 + 1.
high([[Head|Tail]|L], X, H):- not(member(X, Tail)), high(L, X, H).
此预测仅适用于第一种情况,但对于第二种情况不起作用。
如果我运行high([[a,b,c],[d,e,f], [g,h]], X, 1)
,它只返回X = b
,但我希望它一个接一个地返回b,e,h。
为什么它只返回b而失败?
答案 0 :(得分:2)
在不同列表中存在相同元素的情况下,它应该做些什么有点不清楚。不过,这是我使用library(clpfd)
:
:- use_module(library(clpfd)).
high([H|_], X, I) :-
high_(H, X, I, 0).
high([_|T], X, I) :-
high(T, X, I).
high_([X|_], X, I, I).
high_([_|T], X, I, J) :-
J #>= 0,
J #=< I,
J1 #= J + 1,
high_(T, X, I, J1).
这有以下行为:
?- high([[a,b,c],[d,e,f],[g,h]], b, I).
I = 1 ;
false.
?- high([[a,b,c],[d,e,f],[g,h]], f, I).
I = 2 ;
false.
?- high([[a,b,c],[d,e,f],[g,h]], X, 1).
X = b ;
X = e ;
X = h ;
false.
?- high([[a,b,c],[d,e,f],[g,h]], X, 2).
X = c ;
X = f ;
false.
但是当有重复时也有效:
?- high([[a,a],[b,a]], a, X).
X = 0 ;
X = 1 ;
X = 1 ;
false.
有未知的子列表:
?- high([A,B], X, 2).
A = [_4552, _4558, X|_4566] ;
B = [_4552, _4558, X|_4566] ;
false.
列出未知列表:
?- high(L, X, 2).
L = [[_4518, _4524, X|_4532]|_4514] ;
L = [_4512, [_4524, _4530, X|_4538]|_4520] ;
L = [_4512, _4518, [_4530, _4536, X|_4544]|_4526] ;
…
答案 1 :(得分:1)
只返回一个结果,因为只要not(member(X, Tail))
未与任何内容统一(X
不为空),Tail
将永远不会为真。换句话说,由于第二个子句成功,第三个子句不能,并且递归不会继续处理以下列表。
但是,我会说你的方式错了。如果多个子列表中存在元素,则当前代码也会给出错误的输出。
您可以将问题分解为更小的部分:您需要能够在单个简单列表中将其索引与元素相关联;并且您需要能够对总列表中的所有子列表进行评估。
首先要做的事情是:将索引与元素联系起来:
index([X|_], X, 0).
index([_|T], X, I) :- index(T, X, I2), I is I2 + 1.
非常简单易懂,对吧?
现在递归所有列表并匹配其中的所有元素/索引:
high([H|_], X, I) :- index(H, X, I).
high([_|T], X, I) :- high(T, X, I).
这将给出所有预期的输出:
?- high([[a,b,c],[d,e,f], [g,h]], b, X)
X = 1;
false.
?- high([[a,b,c],[d,e,f], [g,h]], f, X)
X = 2;
false.
high([[a,b,c],[d,e,f], [g,h]], X, 1).
X = b;
X = e;
X = h;
false.
high([[a,b,c],[d,e,f], [g,h]], X, 2).
X = c;
X = f;
false.