List PROLOG未定义过程错误(双参数递归)
大家好,我需要帮助。此代码必须递归地提供两个独立数字的计数。但是,我不能提供递归 有两个参数。我猜List PROLOG未定义过程错误(双参数递归),list,recursion,prolog,clpfd,clpb,List,Recursion,Prolog,Clpfd,Clpb,大家好,我需要帮助。此代码必须递归地提供两个独立数字的计数。但是,我不能提供递归 有两个参数。我猜MRec和NRec在任何方面都是无效的。 任何帮助都将不胜感激。现在谢谢…这里有一个更惯用的重写: count([], 0, 0). count([X|T], M, N) :- 1 is X, count(T, MRec, NRec), M is MRec, N is NRec+1. count([X|T], M, N) :- 0 is
MRec
和NRec
在任何方面都是无效的。
任何帮助都将不胜感激。现在谢谢…这里有一个更惯用的重写:
count([], 0, 0).
count([X|T], M, N) :- 1 is X, count(T, MRec, NRec),
M is MRec, N is NRec+1.
count([X|T], M, N) :- 0 is X, count(T, MRec, NRec),
M is MRec+1, N is NRec.
control_number(L) :- count_digit(L, M, N), 2 is M, 3 is N.
?- control_number([1,1,0,0,1]).
ERROR: count_number/3: Undefined procedure: count/3
使用
库(clpfd)
可以大大改进这一点。也许其他人会回答。这里有一个更惯用的重写:
count([], 0, 0).
count([X|T], M, N) :- 1 is X, count(T, MRec, NRec),
M is MRec, N is NRec+1.
count([X|T], M, N) :- 0 is X, count(T, MRec, NRec),
M is MRec+1, N is NRec.
control_number(L) :- count_digit(L, M, N), 2 is M, 3 is N.
?- control_number([1,1,0,0,1]).
ERROR: count_number/3: Undefined procedure: count/3
使用
库(clpfd)
可以大大改进这一点。也许其他人会回答。正如@false已经指出的那样,这个谓词非常适合clpfd。除此之外,我还添加了约束(标记为%,正如@false已经指出的,该谓词是clpfd的一个很好的候选者。除此之外,我还添加了约束(标记为%)累加参数(需要一个辅助谓词来初始化这些参数):
注:
- 您应该调用count/3,而不是count\u aux/5
- 要计数的最后两个参数_aux/5是累加参数
初始化为零
- count_aux/5的第一个子句是基本情况,其中
返回参数
- count_aux/5的最后一个子句在列出项目时防止谓词失败
不是0也不是1
例如:
count(List,C0,C1) :-
count_aux(List,C0,C1,0,0).
count_aux([],C0,C1,C0,C1).
count_aux([0|Rest],C0,C1,PartialC0,PartialC1) :-
IncC0 is PartialC0+1,
!,
count_aux(Rest,C0,C1,IncC0,PartialC1).
count_aux([1|Rest],C0,C1,PartialC0,PartialC1) :-
IncC1 is PartialC1+1,
!,
count_aux(Rest,C0,C1,PartialC0,IncC1).
count_aux([_|Rest],C0,C1,PartialC0,PartialC1) :-
count_aux(Rest,C0,C1,PartialC0,PartialC1).
累积参数是一种方法(您需要一个辅助谓词来初始化这些参数):
注:
- 您应该调用count/3,而不是count\u aux/5
- 要计数的最后两个参数_aux/5是累加参数
初始化为零
- count_aux/5的第一个子句是基本情况,其中
返回参数
- count_aux/5的最后一个子句在列出项目时防止谓词失败
不是0也不是1
例如:
count(List,C0,C1) :-
count_aux(List,C0,C1,0,0).
count_aux([],C0,C1,C0,C1).
count_aux([0|Rest],C0,C1,PartialC0,PartialC1) :-
IncC0 is PartialC0+1,
!,
count_aux(Rest,C0,C1,IncC0,PartialC1).
count_aux([1|Rest],C0,C1,PartialC0,PartialC1) :-
IncC1 is PartialC1+1,
!,
count_aux(Rest,C0,C1,PartialC0,IncC1).
count_aux([_|Rest],C0,C1,PartialC0,PartialC1) :-
count_aux(Rest,C0,C1,PartialC0,PartialC1).
是count_digit
还是count
?t必须是count_digit。İ看不到该错误。现在代码有效。谢谢:)您可以使用内置谓词和库谓词,还是自己编写处理递归的代码?是count_digit
还是count
?t必须是count_digit。İ看不到该错误。现在代码有效。谢谢:)您可以使用内置谓词和库谓词,还是自己编写处理递归的代码?@mat:是的,一个小小的括号移位就可以将整个句子移向语法正确的领域,这真是太神奇了,不是吗?谢谢你的赞誉:-D@mat当前位置是的,一个小括号的移动能使整个句子朝着语法正确的方向移动,这是令人惊讶的,不是吗?谢谢你的赞誉,我真的很脆弱!该代码只在“广告”中起作用。目标count([0,0,1],2,1)
成功(如预期),但更一般的目标count([u,[u,[u,]2,1)
失败!相当脆弱!该代码只在“广告”中起作用。目标count([0,0,1],2,1)
成功(如预期),但更一般的目标count([u,[u,[u,]2,1)
失败!
?- count_digits([1,1,0,0,1],M,N).
M = 2,
N = 3
% 1
?- count_digits([1,0,X,Y],M,N).
M = X = Y = 1,
N = 3 ? ;
M = N = 2,
X = 1,
Y = 0 ? ;
M = N = 2,
X = 0,
Y = 1 ? ;
M = 3,
N = 1,
X = Y = 0
?- count_digits(L,M,N).
L = [],
M = N = 0 ? ;
L = [1],
M = 0,
N = 1 ? ;
L = [1,1],
M = 0,
N = 2 ? ;
L = [1,1,1],
M = 0,
N = 3 ?
...
?- count_digits(L,M,M).
L = [],
M = 0 ? ;
?- length(L,_), count_digits(L,M,M).
L = [],
M = 0 ? ;
L = [1,0],
M = 1 ? ;
L = [0,1],
M = 1 ? ;
L = [1,1,0,0],
M = 2 ? ;
L = [1,0,1,0],
M = 2 ? ;
...
?- length(L,_), count_digits(L,M,N).
L = [],
M = N = 0 ? ;
L = [1],
M = 0,
N = 1 ? ;
L = [0],
M = 1,
N = 0 ? ;
L = [1,1],
M = 0,
N = 2 ? ;
L = [1,0],
M = N = 1 ? ;
...
:- use_module(library(clpfd)).
count_digits(L,M,N) :-
X #= M+N,
length(L,X), % L is of length M+N
list_0s_1s(L,M,N).
list_0s_1s([], 0, 0).
list_0s_1s([1|T], M, N) :-
N #> 0,
NRec #= N-1,
list_0s_1s(T, M, NRec).
list_0s_1s([0|T], M, N) :-
M #> 0,
MRec #= M-1,
list_0s_1s(T, MRec, N).
?- count_digits(L,M,N).
L = [],
M = N = 0 ? ;
L = [1],
M = 0,
N = 1 ? ;
L = [0],
M = 1,
N = 0 ? ;
L = [1,1],
M = 0,
N = 2 ? ;
L = [1,0],
M = N = 1 ?
...
?- count_digits(L,M,M).
L = [],
M = 0 ? ;
L = [1,0],
M = 1 ? ;
L = [0,1],
M = 1 ? ;
L = [1,1,0,0],
M = 2 ? ;
L = [1,0,1,0],
M = 2 ?
...
?- M is 2.
M = 2
% 1
?- 2 is M.
ERROR!!
INSTANTIATION ERROR- in arithmetic: expected bound value
% 1
count(List,C0,C1) :-
count_aux(List,C0,C1,0,0).
count_aux([],C0,C1,C0,C1).
count_aux([0|Rest],C0,C1,PartialC0,PartialC1) :-
IncC0 is PartialC0+1,
!,
count_aux(Rest,C0,C1,IncC0,PartialC1).
count_aux([1|Rest],C0,C1,PartialC0,PartialC1) :-
IncC1 is PartialC1+1,
!,
count_aux(Rest,C0,C1,PartialC0,IncC1).
count_aux([_|Rest],C0,C1,PartialC0,PartialC1) :-
count_aux(Rest,C0,C1,PartialC0,PartialC1).
?- count([1,1,0,0,0,k],A,B).
A = 3,
B = 2.