我正在编写一个小程序,它计算列表中有多少元素不是数字。 这是我的代码:
not_number([],0).
not_number([X|T],R):-
not(number(X)),
R1 is R+1,
not_number(T,R1).
not_number([_|Tail],Result):-
not_number(Tail,Result).
如果我执行这样的代码:
?- not_number([1,2,3,5], R).
我得到R = 0(应该是)
R = 0.
但是如果我在列表中添加一个字符:
?- not_number([1,2,3,5,a], R).
然后我收到了这个错误:
ERROR: not_number/2: Arguments are not sufficiently instantiated
Exception: (10) not_number([a], _G247) ?
有人可以解释代码有什么问题吗?我是prolog的新手。
答案 0 :(得分:16)
我正在写这个答案,因为最好的答案是comment lurker。我想让它显示为一个真正的答案。
您的代码无效,因为R1 is R+1
在案例R
中未not_number([X|T], R)
实例化时您正在执行not_number([X|T],R):-
not(number(X)),
not_number(T,R1),
R is R1+1.
。你的递归案件有点倒退。你想这样做:
is
现在cmd = 'java -jar ' + args
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
的右侧在被调用时被实例化。
答案 1 :(得分:4)
你的问题是在算术计算中这样:
A是B
右侧(B)的所有内容都必须已知。那里没有变数。
您可以这样做:
not_number(X, Y) :- not_number(X, Y, 0).
not_number([], Y, Y).
not_number([H|T], Y, Z) :-
\+ (number(H)),
Z1 is Z+1,
not_number(T, Y, Z1).
not_number([H|T], Y, Z) :-
number(H),
not_number(T, Y, Z).
(现在测试了这段代码,它有效)。
现在第三个参数是累加器。它计算有多少个非数字。当列表为空时,第三个参数与第二个参数统一,它就成了正确的答案。
Prolog,如果有机会,将通过所有可能的路线。如果您这样做:
cat(adam).
cat(eve).
然后问:
?- cat(X).
你可以得到两个答案:X =亚当和X =夏娃。 它也适用于您的代码:请注意,当列表的头部不是数字时,您仍然可以执行此操作:
not_number([_|Tail],Result):-
not_number(Tail,Result).
这不是你想要的答案。你必须切断你不感兴趣的路线。在这种情况下,我会添加
number(Head).
确保我们跳过列表中的元素而不将计数器增加1只有当此元素不是数字时。
要强制Prolog查找其他一些结果,您必须按“;”在键盘上(就像在adam和eve示例中一样)。
答案 2 :(得分:0)
此类问题的一般解决方案是使用约束。
例如,如果您只使用clpfd约束,您的程序将完全按预期工作。只需将(is)/2
替换为(#=)/2
即可获得在所有方向上的整数算术:
:- use_module(library(clpfd)).
not_number([],0).
not_number([X|T],R):-
\+ number(X),
R1 #= R+1,
not_number(T,R1).
not_number([_|Tail],Result):-
not_number(Tail,Result).
示例查询及其结果:
?- not_number([1,2,3,5], R). R = 0.
另请注意,我已将代码更改为使用ISO谓词(\+)/1
而非not/1
。
答案 3 :(得分:0)
就我而言,我不得不使用is
=
代替这个
X is AnotherVariable
我不得不写
X = AnotherVariable