Prolog 找到k';给定元素的出现
我刚开始使用Prolog,遇到了以下问题: (a) 给定一个列表L、一个对象X和一个正整数K,它返回 如果X至少出现在K中,则X在L中第K次出现的位置 以L表示的次数,否则为0 目标Prolog 找到k';给定元素的出现,prolog,clpfd,Prolog,Clpfd,我刚开始使用Prolog,遇到了以下问题: (a) 给定一个列表L、一个对象X和一个正整数K,它返回 如果X至少出现在K中,则X在L中第K次出现的位置 以L表示的次数,否则为0 目标pos([a,b,c,b],b,2,Z)应该成功地回答Z=4 到目前为止,我已经: pos1([],H,K,F). pos1([H],H,1,F). pos1([H|T],H,K,F):- NewK is K - 1, pos1(T,H,NewK,F), F is F + 1. pos1([H|T],X,K,F):-
pos([a,b,c,b],b,2,Z)
应该成功地回答Z=4
到目前为止,我已经:
pos1([],H,K,F).
pos1([H],H,1,F).
pos1([H|T],H,K,F):- NewK is K - 1, pos1(T,H,NewK,F), F is F + 1.
pos1([H|T],X,K,F):- pos1(T,X,K,F).
但我不明白为什么我会:
ERROR: is/2: Arguments are not sufficiently instantiated
任何帮助都将不胜感激 让我们采用一种高层次的方法,用生成代码的效率换取开发的便利性: 位置(L、X、K、P):- 计算(L,X,LN,1),%/[A1,A2,A3…]->[A1-1,A2-2,A3-3…],其中Ai=X。 (drop1(K,LN,[X-P |)]->真;P=0)。 现在我们只实现两个新谓词
drop1(K,L,L2)
从L
中删除K-1
元素,因此剩下L2
:
drop1(K,L2,L2):-kr=[A-I|C];R=C),计算(B,X,C,I1)。
测试:
<代码>5?-计算([1,b,2,b],b,R,1)。
R=[b-2,b-4]。
6?-pos([1,b,2,b],b,2,P)。
P=4。
7?-pos([1,b,2,b],b,3,P)。
P=0。
让我们采用一种高层次的方法来实现它,用生成代码的效率换取开发的便利性: 位置(L、X、K、P):- 计算(L,X,LN,1),%/[A1,A2,A3…]->[A1-1,A2-2,A3-3…],其中Ai=X。 (drop1(K,LN,[X-P |)]->真;P=0)。 现在我们只实现两个新谓词
drop1(K,L,L2)
从L
中删除K-1
元素,因此剩下L2
:
drop1(K,L2,L2):-kr=[A-I|C];R=C),计算(B,X,C,I1)。
测试:
<代码>5?-计算([1,b,2,b],b,R,1)。
R=[b-2,b-4]。
6?-pos([1,b,2,b],b,2,P)。
P=4。
7?-pos([1,b,2,b],b,3,P)。
P=0。
我已经更正了您的代码,但没有更改逻辑,这似乎已经足够简单了。 刚刚添加了一个“顶级”处理程序,将其传递给实际工作人员pos1/4并测试是否工作,否则返回0-在Prolog中,imo最好允许失败,我希望您能理解采用此(请参阅注释)如何简化您的代码
pos(L,X,K,F):- pos1(L,X,K,F) -> true ; F=0.
% pos1([],H,K,F). useless: let it fail
% pos1([H],H,1,F). useless: already handled immediatly bottom
pos1([H|T],H,K,P):- K==1 -> P=1 ; NewK is K - 1, pos1(T,H,NewK,F), P is F + 1.
pos1([_|T],X,K,P):- pos1(T,X,K,F),P is F+1.
我希望允许您使用if/then/else结构。无论如何,收益率
7 ?- pos([a,b,c,b],b,2,Z).
Z = 4.
8 ?- pos([a,b,c,b],b,3,Z).
Z = 0.
我已经更正了您的代码,但没有更改逻辑,这似乎已经足够简单了。 刚刚添加了一个“顶级”处理程序,将其传递给实际工作人员pos1/4并测试是否工作,否则返回0-在Prolog中,imo最好允许失败,我希望您能理解采用此(请参阅注释)如何简化您的代码
pos(L,X,K,F):- pos1(L,X,K,F) -> true ; F=0.
% pos1([],H,K,F). useless: let it fail
% pos1([H],H,1,F). useless: already handled immediatly bottom
pos1([H|T],H,K,P):- K==1 -> P=1 ; NewK is K - 1, pos1(T,H,NewK,F), P is F + 1.
pos1([_|T],X,K,P):- pos1(T,X,K,F),P is F+1.
我希望允许您使用if/then/else结构。无论如何,收益率
7 ?- pos([a,b,c,b],b,2,Z).
Z = 4.
8 ?- pos([a,b,c,b],b,3,Z).
Z = 0.
像这样的。调用内部工作谓词的外部谓词(此谓词强制执行指定的约束):
kth( L , X , K , P ) :-
is_list( L ) , % constraint: L must be a list
nonvar(X) , % constriant: X must be an object
integer(K) , K > 0 % constraint: K must be a positive integer
kth( Ls , X , K , 1 , P ) % invoke the worker predicate with its accumulator seeded to 1
. % easy!
is_list/2
确保您拥有以下列表:
is_list(X) :- var(X) , !, fail .
is_list([]).
is_list([_|_]).
完成所有工作的谓词是:
kth( [] , _ , _ , _ , 0 ) . % if we hit the end of the list, P is 0.
kth( [X|Ls] , X , K , K , K ) :- ! . % if we find the Kth desired element, succeed (and cut: we won't find another Kth element)
kth( [_|Ls] , X , K , N , P ) :- % otherwise
N < K , % - if we haven't got to K yet ...
N1 is N+1 , % - increment our accumulator , and
kth(Ls,X,K,N1,P) % - recurse down.
. % easy!
kth([],[uu,[uu,[u0])%如果我们到达列表的末尾,P是0。
kth([X | Ls],X,K,K,K):-!%如果我们找到了所需的第k个元素,则成功(并剪切:我们将找不到另一个第k个元素)
kth([u124; Ls],X,K,N,P):-%否则
N
如果你问我的话,返回0而不是失败的概念并不是序言的方式。类似这样的东西。调用内部工作谓词的外部谓词(此谓词强制执行指定的约束):
kth( L , X , K , P ) :-
is_list( L ) , % constraint: L must be a list
nonvar(X) , % constriant: X must be an object
integer(K) , K > 0 % constraint: K must be a positive integer
kth( Ls , X , K , 1 , P ) % invoke the worker predicate with its accumulator seeded to 1
. % easy!
is_list/2
确保您拥有以下列表:
is_list(X) :- var(X) , !, fail .
is_list([]).
is_list([_|_]).
完成所有工作的谓词是:
kth( [] , _ , _ , _ , 0 ) . % if we hit the end of the list, P is 0.
kth( [X|Ls] , X , K , K , K ) :- ! . % if we find the Kth desired element, succeed (and cut: we won't find another Kth element)
kth( [_|Ls] , X , K , N , P ) :- % otherwise
N < K , % - if we haven't got to K yet ...
N1 is N+1 , % - increment our accumulator , and
kth(Ls,X,K,N1,P) % - recurse down.
. % easy!
kth([],[uu,[uu,[u0])%如果我们到达列表的末尾,P是0。
kth([X | Ls],X,K,K,K):-!%如果我们找到了所需的第k个元素,则成功(并剪切:我们将找不到另一个第k个元素)
kth([u124; Ls],X,K,N,P):-%否则
N
尽管返回0而不是失败的概念不是序言的方式,如果你问我的话。使用强>
:- use_module(library(clpfd)).
我们根据、和定义pos/4:
pos(Xs,E,K,P):-
K#>0,
位置辅助(X、E、K、1、P)。
pos|aux([X|Xs],E,K,P0,P):-
P0+1#=P1,
如果_uf(X,E),
位置辅助(X、E、K、P1、P),
如果(K)<2,
P0=P,
(K0+1#=K,
位置(X、E、K0、P1、P))。
OP给出的示例查询:
?- X = b, N = 2, pos([a,b,c,b],X,N,P).
X = b, N = 2, P = 4. % succeeds deterministically
?-X=b,N=2,位置([a,b,c,b],X,N,P)。
X=b,N=2,P=4%决定性地成功
下面这个更一般的查询怎么样
?- pos([a,b,c,b],X,N,P).
X = a, N = 1, P = 1
; X = b, N = 1, P = 2
; X = b, N = 2, P = 4 % (exactly like in above query)
; X = c, N = 1, P = 3
; false.
?-pos([a,b,c,b],X,N,P)。
X=a,N=1,P=1
; X=b,N=1,P=2
; X=b,N=2,P=4%(与上述查询完全相同)
; X=c,N=1,P=3
; 错。
使用强>
:- use_module(library(clpfd)).
我们根据、和定义pos/4:
pos(Xs,E,K,P):-
K#>0,
位置辅助(X、E、K、1、P)。
pos|aux([X|Xs],E,K,P0,P):-
P0+1#=P1,
如果_uf(X,E),
位置辅助(X、E、K、P1、P),
如果(K)<2,
P0=P,
(K0+1#=K,
位置(X、E、K0、P1、P))。
OP给出的示例查询:
?- X = b, N = 2, pos([a,b,c,b],X,N,P).
X = b, N = 2, P = 4. % succeeds deterministically
?-X=b,N=2,位置([a,b,c,b],X,N,P)。
X=b,N=2,P=4%决定性地成功
下面这个更一般的查询怎么样
?- pos([a,b,c,b],X,N,P).
X = a, N = 1, P = 1
; X = b, N = 1, P = 2
; X = b, N = 2, P = 4 % (exactly like in above query)
; X = c, N = 1, P = 3
; false.
?-pos([a,b,c,b],X,N,P)。
X=a,N=1,P=1
; X=b,N=1,P=2
; X=b,N=2,P=4%(与上述查询完全相同)
; X=c,N=1,P=3
; 错。
你真的在查阅这个文件吗?我直接从文件中加载它你用什么命令直接从文件中加载?我只是点击我的.pl文件,它就会加载它