Prolog平均规则

时间:2015-02-27 09:42:59

标签: prolog average

以下一套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返回正确的值?

2 个答案:

答案 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}.

虚假评论后的编辑纠正。