以下一套Prolog规则适用于average([3,4,5],A).
Where A = 4.0
等输入。
但是,如果我尝试average([3,4,X],4).
之类的内容,则会返回以下错误:
average([X|Xs],A) :- sum([X|Xs],S), length([X|Xs],L), {S/L=A}.
ERROR: is/2: Arguments are not sufficiently instantiated
如何修改我的代码以允许average([3,4,X],4)
为X
返回正确的值?
答案 0 :(得分:3)
带库的简单解决方案(clpqr):
add(A, B, +(A,B)).
list_average([X|Xs], A) :-
length([X|Xs], Len),
foldl(add, Xs, X, Sum),
{Sum =:= A*Len}.
如果由于某种原因您不想使用该库,则可以尝试以下代码。 这可能会解决您的问题,但我对此代码不满意。当然别人知道的更好:
list_average(L, A) :-
( is_list(L)
-> length(L, Len),
term_variables(L-A, Vars),
solve(Vars, L, A, Len)
; instantiation_error(L)
).
solve([], L, A, Len) :-
sum_list(L, Sum),
A =:= Sum / Len. % Validate provided average
solve([X|Xs], L, A, Len) :-
partition(number, L, Nums, Vars),
length(Vars, T),
sum_list(Nums, Sum),
( var(A)
-> maplist(=(A), Vars), % all variables are as the average
A is Sum / (Len - T)
; maplist(=(X), Xs), % all free variables in list are same
X is (Len*A - Sum) / T
).
这样的查询是可能的:
?- list_average([2,3,4,5], A).
A = 3.5.
?- list_average([2,3,4,5], 3).
false.
?- list_average([2,X,4,5], 3).
X = 1.
?- list_average([2,X,4,Y], 3).
X = Y, Y = 3.
?- list_average([2,X,4,Y], A).
X = Y, Y = A, A = 3.
?- list_average([2,X,4,Y], 6).
X = Y, Y = 9.
在以数字方式求解之前,它会自动尝试将所有自由变量绑定到单个自由变量。
答案 1 :(得分:3)
它与Boris解决方案完全相同,但我使用库lambda:
:- use_module(library(clpr)).
:- use_module(library(lambda)).
average(L, A) :-
length(L, Len),
foldl(\X^Y^Z^{Z = X+Y}, L, 0, TT),
{A * Len = TT}.
虚假评论后的编辑纠正。