用树中的 0 替换叶原子并在 Prolog 中列出
Replacing leaf atoms by the 0 in a tree and lists in Prolog
我坚持使用以下 Prolog 代码:
islist([]).
islist([A|B]) :-
islist(B).
memb([X|_]).
memb([Y|Z]) :-
islist(Y),
memb(Y).
memb([_|Z]) :-
memb(Z).
deep([],[]).
deep([H|P],[M|N]) :-
islist(H),
deep(H,M),
deep(P,N).
deep([Y|P],[Y|N]) :-
number(Y),
deep(P,N).
deep([H|P],[M|N]) :-
atom(H),
M is 0,
deep(P,N).
deep([Y|P],[H|Q]) :-
not(number(Y)),
not(islist(Y)),
not(atom(Y)),
Y =.. T,
deep(T,F),
H =.. F,
deep(P,Q),
!.
当我尝试 运行 时它让我失败了。
我做不到。请帮忙。我不明白我哪里错了...
第一个问题是您误用了 univ/2(即 (=..)/2)。将最后一个子句更改为
deep([Y|P],[H|Q]):-
not(number(Y)),
not(islist(Y)),
not(atom(Y)),
Y=..[T|YArgs],
deep(YArgs,HArgs),
H=..[T|HArgs],
deep(P,Q),!.
您将获得所需的行为
?- deep([14,dog,a(b,27,c(16,[g]))],A).
A = [14, 0, a(0, 27, c(16, [0]))]
请注意,作为最后一个子句的最后目标的 cut 没有任何效果。完全没有用,但它的用法表明你需要更多地研究Prolog执行模式。
当我简单地获取你的程序、加载它、忽略单例警告并跟踪它时,我最终得到:
Call: (14) _G2807=..[0, 16, [0]] ? creep
ERROR: =../2: Type error: `atom' expected, found `0' (an integer)
Exception: (14) _G2807=..[0, 16, [0]] ?
所以,每次你得到一个函子,你首先分解它,像这样:
foo(1, bar) ---> [foo, 1, bar] % in your code: Y=..T
然后用 0 替换原子:
[foo, 1, bar] ---> [0, 1, 0] % in your code: deep(T,F)
然后您出于某种原因尝试再次从中创建仿函数:
[0, 1, 0] ---> 0(1, 0) % in your code: H=..F
这当然不行,也不是你要的,看来:
foo(1, bar) ---> foo, [1, bar] % Y =.. [Name|Args]
那么,您可以只转换列表:
[1, bar] ---> [1, 0] % deep(Args, Args1)
并重新创建术语:
foo, [1, 0] ---> foo(1, 0) % H =.. [Name|Args1]
在程序中进行了这些更正:
?- deep([14,dog,a(b,27,c(16,[g]))],A).
A = [14, 0, a(0, 27, c(16, [0]))] ;
false.
但是你完全可以让程序简单一点。首先,我认为您不需要定义的 memb/1
:摆脱它。然后,您还可以在该定义中使用另一个子句:
islist(X) :-
var(X), !,
fail.
islist([]).
islist([_|T]) :-
islist(T).
稍微清理其余代码的一种方法是编写:
deep([], []).
deep([X|Xs], [Y|Ys]) :-
once( deep_1(X, Y) ),
deep(Xs, Ys).
deep_1(X, Y) :- islist(X), deep(X, Y).
deep_1(X, X) :- number(X).
deep_1(X, 0) :- atom(X).
deep_1(X, Y) :- compound(X),
X =.. [Name|Args],
deep(Args, Args1),
Y =.. [Name|Args1].
如您所见,目前,如果您有变量(或任何其他无法识别的术语),程序将失败:
?- deep([14,dog,a(b,27,c(16,[g]))],A).
A = [14, 0, a(0, 27, c(16, [0]))].
?- deep([14,Dog,a(b,27,c(16,[g]))],A).
false.
您只需添加类型即可轻松扩展程序:
deep_1(X, X) :- string(X).
然后:
?- deep([14,"Dog",a(b,27,c(16,[g]))],A).
A = [14, "Dog", a(0, 27, c(16, [0]))].
?- deep([14,Dog,a(b,27,c(16,[g]))],A).
false.
?- deep([14,dog,a(b,27,c(16,[g]))],A).
A = [14, 0, a(0, 27, c(16, [0]))].
我坚持使用以下 Prolog 代码:
islist([]).
islist([A|B]) :-
islist(B).
memb([X|_]).
memb([Y|Z]) :-
islist(Y),
memb(Y).
memb([_|Z]) :-
memb(Z).
deep([],[]).
deep([H|P],[M|N]) :-
islist(H),
deep(H,M),
deep(P,N).
deep([Y|P],[Y|N]) :-
number(Y),
deep(P,N).
deep([H|P],[M|N]) :-
atom(H),
M is 0,
deep(P,N).
deep([Y|P],[H|Q]) :-
not(number(Y)),
not(islist(Y)),
not(atom(Y)),
Y =.. T,
deep(T,F),
H =.. F,
deep(P,Q),
!.
当我尝试 运行 时它让我失败了。
我做不到。请帮忙。我不明白我哪里错了...
第一个问题是您误用了 univ/2(即 (=..)/2)。将最后一个子句更改为
deep([Y|P],[H|Q]):-
not(number(Y)),
not(islist(Y)),
not(atom(Y)),
Y=..[T|YArgs],
deep(YArgs,HArgs),
H=..[T|HArgs],
deep(P,Q),!.
您将获得所需的行为
?- deep([14,dog,a(b,27,c(16,[g]))],A).
A = [14, 0, a(0, 27, c(16, [0]))]
请注意,作为最后一个子句的最后目标的 cut 没有任何效果。完全没有用,但它的用法表明你需要更多地研究Prolog执行模式。
当我简单地获取你的程序、加载它、忽略单例警告并跟踪它时,我最终得到:
Call: (14) _G2807=..[0, 16, [0]] ? creep
ERROR: =../2: Type error: `atom' expected, found `0' (an integer)
Exception: (14) _G2807=..[0, 16, [0]] ?
所以,每次你得到一个函子,你首先分解它,像这样:
foo(1, bar) ---> [foo, 1, bar] % in your code: Y=..T
然后用 0 替换原子:
[foo, 1, bar] ---> [0, 1, 0] % in your code: deep(T,F)
然后您出于某种原因尝试再次从中创建仿函数:
[0, 1, 0] ---> 0(1, 0) % in your code: H=..F
这当然不行,也不是你要的,看来:
foo(1, bar) ---> foo, [1, bar] % Y =.. [Name|Args]
那么,您可以只转换列表:
[1, bar] ---> [1, 0] % deep(Args, Args1)
并重新创建术语:
foo, [1, 0] ---> foo(1, 0) % H =.. [Name|Args1]
在程序中进行了这些更正:
?- deep([14,dog,a(b,27,c(16,[g]))],A).
A = [14, 0, a(0, 27, c(16, [0]))] ;
false.
但是你完全可以让程序简单一点。首先,我认为您不需要定义的 memb/1
:摆脱它。然后,您还可以在该定义中使用另一个子句:
islist(X) :-
var(X), !,
fail.
islist([]).
islist([_|T]) :-
islist(T).
稍微清理其余代码的一种方法是编写:
deep([], []).
deep([X|Xs], [Y|Ys]) :-
once( deep_1(X, Y) ),
deep(Xs, Ys).
deep_1(X, Y) :- islist(X), deep(X, Y).
deep_1(X, X) :- number(X).
deep_1(X, 0) :- atom(X).
deep_1(X, Y) :- compound(X),
X =.. [Name|Args],
deep(Args, Args1),
Y =.. [Name|Args1].
如您所见,目前,如果您有变量(或任何其他无法识别的术语),程序将失败:
?- deep([14,dog,a(b,27,c(16,[g]))],A).
A = [14, 0, a(0, 27, c(16, [0]))].
?- deep([14,Dog,a(b,27,c(16,[g]))],A).
false.
您只需添加类型即可轻松扩展程序:
deep_1(X, X) :- string(X).
然后:
?- deep([14,"Dog",a(b,27,c(16,[g]))],A).
A = [14, "Dog", a(0, 27, c(16, [0]))].
?- deep([14,Dog,a(b,27,c(16,[g]))],A).
false.
?- deep([14,dog,a(b,27,c(16,[g]))],A).
A = [14, 0, a(0, 27, c(16, [0]))].