Prolog 如何使我的关系发挥作用

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

我有以下关系:索引(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
未被实例化为数字类型。这会导致您报告的实例化错误

我不知道如何直接解决你的问题,但我有两个建议。第一种方法是使用累加器,以便可以计算递归子句中的算术运算:

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.