Prolog 如何使我的关系发挥作用
我有以下关系:索引(X,N,List) 例如:Prolog 如何使我的关系发挥作用,prolog,Prolog,我有以下关系:索引(X,N,List) 例如: index(X,2,[a,b,c]). X=b index(b,N,[a,b,c]). N=2 我不知道如何使我与第二个例子的关系起作用。它说N没有很好的定义 这是我的代码(对于第一个示例,它工作得很好) 当Prolog试图评估定义索引/3的递归子句中的目标N>1且N1为N-1时,变量N未被实例化为数字类型。这会导致您报告的实例化错误 我不知道如何直接解决你的问题,但我有两个建议。第一种方法是使用累加器,以便可以计算递归子句中的算术运算: ge
index(X,2,[a,b,c]).
X=b
index(b,N,[a,b,c]).
N=2
我不知道如何使我与第二个例子的关系起作用。它说N没有很好的定义
这是我的代码(对于第一个示例,它工作得很好)
当Prolog试图评估定义
索引/3
的递归子句中的目标N>1
且N1为N-1
时,变量N
未被实例化为数字类型。这会导致您报告的实例化错误
我不知道如何直接解决你的问题,但我有两个建议。第一种方法是使用累加器,以便可以计算递归子句中的算术运算:
get(M,Xs,X) :- get(1,M,Xs,X).
get(N,N,[X|_],X).
get(N,M,[_|Xs],X) :-
L is N + 1,
get(L,M,Xs,X).
例如:
?- index(N,[a,b],X).
N = 1,
X = a ;
N = 2,
X = b ;
false.
另一种是使用自然数类型,以便通过统一构建索引:
nat(0).
nat(s(N)) :- nat(N).
get(s(0),[X|_],X).
get(s(N),[_|Y],X) :- get(N,Y,X).
比如说,
?- get(N,[a,b],X).
N = s(0),
X = a ;
N = s(s(0)),
X = b ;
false.
希望这是有帮助的。也许会有更有知识的人来提供更好的解决方案。有一个内置的SWI Prolog
nth1/3
可以满足您的需要:
?- nth1(N, [a, b, c], b).
N = 2 ;
false.
看看它的源代码:
?- listing(nth1).
lists:nth1(A, C, D) :-
integer(A), !,
B is A+ -1,
nth0_det(B, C, D).
lists:nth1(A, B, C) :-
var(A), !,
nth_gen(B, C, 1, A).
true.
?- listing(nth0_det).
lists:nth0_det(0, [A|_], A) :- !.
lists:nth0_det(1, [_, A|_], A) :- !.
lists:nth0_det(2, [_, _, A|_], A) :- !.
lists:nth0_det(3, [_, _, _, A|_], A) :- !.
lists:nth0_det(4, [_, _, _, _, A|_], A) :- !.
lists:nth0_det(5, [_, _, _, _, _, A|_], A) :- !.
lists:nth0_det(A, [_, _, _, _, _, _|C], D) :-
B is A+ -6,
B>=0,
nth0_det(B, C, D).
true.
?- listing(nth_gen).
lists:nth_gen([A|_], A, B, B).
lists:nth_gen([_|B], C, A, E) :-
succ(A, D),
nth_gen(B, C, D, E).
true.
谢谢,我找到的解决方案更简单。。。第二行是:索引(X,N,[| Tail]):-索引(X,N1,Tail),N是N1+1。
?- listing(nth1).
lists:nth1(A, C, D) :-
integer(A), !,
B is A+ -1,
nth0_det(B, C, D).
lists:nth1(A, B, C) :-
var(A), !,
nth_gen(B, C, 1, A).
true.
?- listing(nth0_det).
lists:nth0_det(0, [A|_], A) :- !.
lists:nth0_det(1, [_, A|_], A) :- !.
lists:nth0_det(2, [_, _, A|_], A) :- !.
lists:nth0_det(3, [_, _, _, A|_], A) :- !.
lists:nth0_det(4, [_, _, _, _, A|_], A) :- !.
lists:nth0_det(5, [_, _, _, _, _, A|_], A) :- !.
lists:nth0_det(A, [_, _, _, _, _, _|C], D) :-
B is A+ -6,
B>=0,
nth0_det(B, C, D).
true.
?- listing(nth_gen).
lists:nth_gen([A|_], A, B, B).
lists:nth_gen([_|B], C, A, E) :-
succ(A, D),
nth_gen(B, C, D, E).
true.