我正在尝试实现一个带有一组形式为{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) 在上一篇文章中,我最终想出了如何编写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 …
因此,我有一个适用于未实例化变量的谓词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任何不同。
抱歉,这个菜鸟问题,很多概念对我来说都是新的,我仍在尝试处理这一切。
使用 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中实现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) 我想知道为什么在这些情况下程序会无限递归:
?- 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)