Prolog nth1匿名变量

时间:2017-05-15 17:25:17

标签: prolog prolog-toplevel

我有一个带有整数和匿名变量的List,我试着找到一个特殊值的索引。问题是我正在使用nth1/3来查找索引Prolog为匿名变量分配值,因此我也找到了索引。

实施例: List = [1,\_,1]X = 1, X = 3 nth1(X,List,1)X = 1, X = 2, X = 3@Path("{productId : .+}") create view main_summary ( team, minors, adults) as select all_teams.team_name as team , case when age<18 then count(id) as minors, case when age>= 18 then count(id) as adults from all_teams ; 。{/ 1}}

3 个答案:

答案 0 :(得分:5)

您的要求中隐藏着一个有问题的问题:他们违反一个名为单调性的重要声明属性。我们的意思是添加约束最多可以使解决方案更具体,而不是更通用。

例如,根据您发布的解决方案,我们得到:

?- list_el_index([_], 1, N).
false.

现在我通过对迄今为止免费的匿名变量强加额外要求来添加约束:

?- Var = 1, list_el_index([Var], 1, N).
Var = 1,
N = 0 .

我的意思是:来吧!我们添加了一个约束,结果得到更多解决方案?这样的结果是不幸的,并且阻止我们以逻辑的方式推理这个程序。

该计划在其他方面也使我们失望。例如,让我们问:有哪些解决方案?

?- list_el_index(Ls, El, I).
nontermination

理想情况下,我们希望程序在这种情况下生成解决方案!这种普遍性是逻辑编程最重要的吸引力之一,并将其​​与更低级别的范例区分开来。

解决此类问题的一种方法是象征性地区分列表中显示的元素的不同

例如,让我们使用:

  • u表示未知值。
  • i(I)表示整数 I

通过这种新的表示形式,您的解决方案将成为:

list_el_index([i(I)|_], I, 0).
list_el_index([_|Tail], Element, Index) :-
    list_el_index(Tail, Element, Index0),
    Index #= Index0+1.

我还冒昧地将(is)/2替换为(#=)/2,以宣传并坚持使用更通用的整数运算,如果有必要,我们可以更自由地重新排序目标。根据您的Prolog实现,您可能必须导入库才能从(#=)/2中受益。

通过此表示,您的初始案例将变为:

?- list_el_index([i(1),u,i(1)], 1, Index).
Index = 0 ;
Index = 2 ;
false.

这可以按预期工作!

重要的是,我们也可以使用谓词更一般地,即生成可能的答案:

?- list_el_index(Ls, El, I).
Ls = [i(El)|_2994],
I = 0 ;
Ls = [_2992, i(El)|_3000],
I = 1 ;
Ls = [_2992, _2998, i(El)|_3006],
I = 2 ;
Ls = [_2992, _2998, _3004, i(El)|_3012],
I = 3 .

由于程序的单调性,我们可以通过迭代深化来公平地枚举解决方案

?- length(Ls, _), list_el_index(Ls, El, I).
Ls = [i(El)],
I = 0 ;
Ls = [i(El), _4812],
I = 0 ;
Ls = [_4806, i(El)],
I = 1 ;
Ls = [i(El), _4812, _4818],
I = 0 ;
etc.

通过使用能够通过模式匹配来区分案例的表示,这已成为可能。考虑使用这种方法使您的程序可以在所有方向上使用,并使逻辑推理适用。使用适当的包装器或常量非常容易应用,并大大提高了程序的通用性。

答案 1 :(得分:2)

这有效:

 - L = [1,_,1], nth1(X, L, Y), ground(Y), Y= 1.
L = [1,_310914,1],
X = Y, Y = 1 ;
L = [1,_310914,1],
X = 3,
Y = 1.

答案 2 :(得分:1)

感谢潜伏者提示,我提出了这个解决方案。

list_el_index([El1|_], El2, 0) :-
    El1 == El2.
list_el_index([_|Tail], Element, Index) :-
    list_el_index(Tail, Element, Index1),
    Index is Index1+1.
相关问题