第一个元素的索引大于X(Prolog)

bgi*_*ers 4 list prolog clpfd

我知道如何在Prolog中找到特定元素的索引,但有没有办法找到大于say的数字的第一个实例的索引X.例如,假设我有一个列表,但是列表中的某个地方有一个大于1的随机数.我怎样才能找到大于的第一个实例的索引1?我是Prolog的新手,并且不太善于谓词的子目标.

tas*_*tas 5

您希望在列表,索引之间编写关系.我们称之为list_1stindex_gt/3.有第四个参数来跟踪当前指数是恰当的.但是,不用这个累加器来打扰用户会很好,所以你可以使用辅助谓词和当前索引的附加参数,我们称之为list_1stindex_gt_/4.假设您想要开始计算索引1(否则将第四个参数更改为0),您可以像这样定义list_1stindex_gt/3:

:-use_module(library(clpfd)).

list_1stindex_gt(L,I,GT) :-
   list_1stindex_gt_(L,I,GT,1).
Run Code Online (Sandbox Code Playgroud)

对于list_1stindex_gt_/4,你有2个案例:

  1. 列表的头部大于第三个参数:然后您知道所需的索引.

  2. 列表的头部小于或等于第三个参数:然后递增累加器1并继续搜索列表的尾部.

你可以在Prolog中写这样的:

list_1stindex_gt_([X|Xs],I,GT,I) :-       % case 1
   X #> GT.
list_1stindex_gt_([X|Xs],I,GT,Acc0) :-    % case 2
   X #=< GT,
   Acc1 #= Acc0+1,
   list_1stindex_gt_(Xs,I,GT,Acc1).
Run Code Online (Sandbox Code Playgroud)

示例查询:在给定列表中哪个索引是第一个大于1的元素?

   ?- list_1stindex_gt([1,1,1,1,5,1,1,2],I,1).
I = 5 ? ;
no
Run Code Online (Sandbox Code Playgroud)

在哪个索引处,大于1的第一个元素可以在三个变量的列表中?

   ?- list_1stindex_gt([A,B,C],I,1).
I = 1,
A in 2..sup ? ;
I = 2,
A in inf..1,
B in 2..sup ? ;
I = 3,
A in inf..1,
B in inf..1,
C in 2..sup ? ;
no
Run Code Online (Sandbox Code Playgroud)

在哪个索引处,大于变量的第一个元素X可以在三个变量的列表中?

   ?- list_1stindex_gt([A,B,C],I,X).
I = 1,
X#=<A+ -1 ? ;
I = 2,
X#>=A,
X#=<B+ -1 ? ;
I = 3,
X#>=A,
X#=<C+ -1,
X#>=B ? ;
no
Run Code Online (Sandbox Code Playgroud)

此外,你可以考虑@席的建议改进从这个答案由你上一个问题:背后遵循的理念(#<)/ 3,你可以定义(#>)/ 3,然后定义list_1stindex_gt_/4使用if_/3,像这样:

:-use_module(library(clpfd)).

#>(X, Y, T) :-
        zcompare(C, X, Y),
        greater_true(C, T).

greater_true(<, false).
greater_true(>, true).
greater_true(=, false).

list_1stindex_gt(L,I,GT) :-
   list_1stindex_gt_(L,I,GT,1).

list_1stindex_gt_([X|Xs],I,GT,Acc0) :-
   if_(X #> GT,
       (I #= Acc0),
       (Acc1 #= Acc0+1, list_1stindex_gt_(Xs,I,GT,Acc1))).
Run Code Online (Sandbox Code Playgroud)

这样,第一个查询成功,而不会留下不必要的选择点:

?- list_1stindex_gt([1,1,1,1,5,1,1,2],I,1).
I = 5.
Run Code Online (Sandbox Code Playgroud)