我有一个带有整数和匿名变量的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}}
答案 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.