标签: failure-slice

DCG和左递归

我正在尝试实现一个带有一组形式为{a,b,c,d}*的字符串的dcg.我遇到的问题是如果我有一个形式s的查询([a,c,b], []),它返回true,这是正确的答案但是当我有一个形式s([a,c,f],[])的查询时,它不返回一个答案,它用完了本地堆栈.

s --> [].
s --> s,num.
num --> [a].
num--> [b].
num--> [c].
num--> [d].
Run Code Online (Sandbox Code Playgroud)

prolog left-recursion dcg failure-slice

2
推荐指数
1
解决办法
1220
查看次数

这个prolog排序程序是否仅仅因为其复杂性而溢出堆栈 - 或者因为它是错误的?

在上一篇文章中,我最终想出了如何编写gprolog程序来检查一个列表是否是另一个列表的排列.据我所知,它有效.

现在,我正在创建一个mysort谓词,它将排列谓词与这个谓词结合起来(据我所知也是如此):

sorted([]).   
sorted([L]) :- !.  
sorted([L|[T|TT]]) :- L @=< T, sorted([T|TT]).
Run Code Online (Sandbox Code Playgroud)

由于我的原始perm谓词设计!为在得到答案后立即终止,我做了一些修改以允许mysort检查可能性.这是mysort,它的特殊性backtrack_perm,与旧的重叠perm(我只是稍作改动backtrack_perm):

perm([],[]).
perm([LH|LT],R) :-
   backtrack_perm([LH|LT],R),
   !.

perm_recurse([],X). 
perm_recurse([LH|LT],R) :-
   member(LH,R),
   select(LH,[LH|LT],X),
   select(LH,R,Y),
   perm_recurse(X,Y),
   !. 

mysort(L,M) :-
   backtrack_perm(L,M),
   sorted(M),
   !.  

backtrack_perm([],[]).
backtrack_perm([LH|LT],R) :-
   length([LH|LT],A),
   length(R,B),
   A == B,
   member(LH,R),
   select(LH,[LH|LT],X),
   select(LH,R,Y),
   perm_recurse(X, Y).  
Run Code Online (Sandbox Code Playgroud)

虽然它的组件看起来像上面提到的那样正常,但是mysort在某些输入上会导致堆栈溢出,例如mysort([5,3,2],X).在已经排序的列表中,例如mysort([2,3,5],X),甚至是部分类似的列表mysort([3,2,5],X),跟踪可能很长,但它确实得到了答案.正因为如此 - 并且因为一个较小的完全向后的列表就像[2,1]工作正常 - 我认为问题只是过程本身太空/耗时所有这些排列.

如果没有步进深地进入较长的痕迹,这将是安全的假设,这样的话?或者Prolog …

prolog failure-slice

2
推荐指数
1
解决办法
164
查看次数

谓词顺序改变导致无限循环

因此,我有一个适用于未实例化变量的谓词nat_cset(N,Cs),它将自然数与计数集相关联Sn = {1,2,...,N}

nat_cset_(0,Acc,Acc).
nat_cset_(N,Acc,Cs) :- N #> 0, N_1 #= N - 1,  nat_cset_(N_1, [N|Acc], Cs).
nat_cset(N,Cs) :- nat_cset_(N,[],Cs).
Run Code Online (Sandbox Code Playgroud)

我注意到的一件事是,以下查询进入无限循环,而没有nat_cset(N,Cs), N = 6.进入无限循环:N = 6, nat_cset(N,Cs).

?- nat_cset(N,Cs), N = 6, false.
...
?- N = 6, nat_cset(N,Cs), false.
false
Run Code Online (Sandbox Code Playgroud)

发生这种情况是因为在第二个查询中,prolog 应该只查找 N = 6 的解,而在第一个查询中,prolog 将搜索无限解,使得 N = 6。

我的问题是,这是“适当”的行为nat_cset/2还是不受欢迎的行为?我在某处读到,改变解决方案的谓词顺序使其不单调并消除了其纯度,但同时我想不出一种方法可以做出nat_cset/2任何不同。

抱歉,这个菜鸟问题,很多概念对我来说都是新的,我仍在尝试处理这一切。

prolog failure-slice

2
推荐指数
1
解决办法
134
查看次数

寻找多个答案时如何避免全局堆栈错误?

使用 SWI-Prolog 加载以下程序并输入查询后,例如

cells([o,x,o,x,o], A).
Run Code Online (Sandbox Code Playgroud)

或者

cells(A, [o,x,o,x,o]).
Run Code Online (Sandbox Code Playgroud)

第一个结果似乎总是正确的,但是在提交分号以查找更多结果之后(我不知道在这两种情况下是否应该有其他结果),我收到一个 PROLOG SYSTEM ERROR 提到垃圾收集和一个 Out of global分别是堆栈错误。

regla(o,o,o,o).
regla(x,o,o,x).
regla(o,x,o,o).
regla(o,o,x,x).
regla(x,o,x,x).
regla(x,x,o,x).
regla(o,x,x,x).
regla(x,x,x,o).

cells([X | XS], [Y | YS]) :-
    X = o,
    Y = o,
    length([X | XS], LX),
    LX >= 3,
    length([Y | YS], LY),
    LY is LX + 2,
    append([o, o], [X | XS], W),
    append(W, [o, o], Z),
    cellsR(Z, [Y | YS]).

cellsR(_, []).
cellsR([A, B, C | R], [H | T]) :-
    regla(A, B, …
Run Code Online (Sandbox Code Playgroud)

prolog failure-slice

1
推荐指数
1
解决办法
289
查看次数

Prolog毫无理由地退出本地堆栈

我正在尝试在Prolog中实现Levenshtein距离

实现非常简单:

levenshtein(W1, W2, D) :-
    atom_length(W1, L1),
    atom_length(W2, L2),
    lev(W1, W2, L1, L2, D),
    !.

lev(_, _, L1, 0, D) :- D is L1, !.
lev(_, _, 0, L2, D) :- D is L2, !.
lev(W1, W2, L1, L2, D) :-
  lev(W1, W2, L1 - 1, L2, D1),
  lev(W1, W2, L1, L2 - 1, D2),
  lev(W1, W2, L1 - 1, L2 - 1, D3),
  charAt(W1, L1, C1),
  charAt(W2, L2, C2),
  ( C1 = C2 -> T is …
Run Code Online (Sandbox Code Playgroud)

prolog levenshtein-distance non-termination failure-slice

0
推荐指数
1
解决办法
117
查看次数

为什么在定义转换两个原子关系的谓词时会出现堆栈限制超出错误?

我想知道为什么在这些情况下程序会无限递归:

?- love(kay, amanda).
Run Code Online (Sandbox Code Playgroud)

?- love(rob, amanda).
Run Code Online (Sandbox Code Playgroud)

这是代码:

love(amanda, kay).
love(kay, geo).
love(geo, rob).

love(X, Y) :-
   love(X, Z),
   love(Z, Y).
love(X, Y) :-
   love(Y, X).
Run Code Online (Sandbox Code Playgroud)

prolog transitive-closure non-termination failure-slice

0
推荐指数
1
解决办法
417
查看次数