如何使我的关系工作

时间:2011-06-06 06:49:51

标签: prolog

我有以下关系:index(X,N,List)。

例如:

index(X,2,[a,b,c]).
X=b

index(b,N,[a,b,c]).
N=2

我不知道如何使我的关系与第二个例子一起工作。它说N没有很好地定义 这是我的代码(适用于第一个示例)。

index(X,1,[X|_]).
index(X,N,[_|Tail]) :- N > 1, N1 is N - 1 , index(X,N1,Tail).

2 个答案:

答案 0 :(得分:0)

当Prolog尝试评估定义N的递归子句中的目标N > 1N1 is N - 1时,变量index/3尚未实例化为数字类型。这会导致您报告的实例化错误。

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

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.

希望这很有帮助。也许更有知识的人会出现并提供更好的解决方案。

答案 1 :(得分:0)

有一个内置nth1/3的SWI-Prolog可以满足您的需求:

?- 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.