【问题标题】:Accessing coefficients in a numerical expression (clpr)访问数值表达式中的系数 (clpr)
【发布时间】:2019-02-21 14:33:29
【问题描述】:

我有一些子句,其中头部表示线性方程中一组变量的名称和值,而主体表示实际方程。像这样:

:-use_module(library(clpr)).    
relation(
        independents([
            var(x1, X1),
            var(x2, X2),
            var(x3, X3)
        ]),
        dependent(
            var(y, Y)
        )
    ):- {Y = 3 + 0.5 * X1 + 0.6 * X2 + 0.7 * X3}.

有没有一种直接的方法来(间接地)得到这个方程的系数? IE。返回 coefficient(VARNAME, COEFFICIENT) 的规则,例如coefficient(x1, 0.5), coefficient(x2, 0.6) 等等。

我知道这似乎是一个愚蠢的问题,因为将所有系数都放在子句的头部很容易。但是在我的应用程序中,我希望这些子句的开头严格显示每个变量的值(而不是它们的系数)。 IE。避免歧义。

我目前的解决方案是一个复杂且不雅的解决方案,涉及 member/2subtract/3maplist/2 并将 X1、X2、X3 设置为 1 或 0 以计算每个斜率。

相关问题: Representing linear functions in prolog

谢谢!

/JC

【问题讨论】:

    标签: prolog clpr


    【解决方案1】:

    这是我第一次使用clpr,所以如果这对你没有帮助,我恳求精神错乱,但对我来说,这里的关键似乎是使用dump/3 将约束转换回Prolog 表达式,然后遍历它像任何其他结构一样。所以我通过这样做再次获得约束:

    ?- relation(independents([var(x1,X1),var(x2,X2),var(x3,X3)]),
                dependent(var(y,Y))), 
       dump([X1,X2,X3,Y],[x1,x2,x3,y], [y=Eqn]).
    Eqn = 3.0+0.5*x1+0.6*x2+0.7*x3
    

    我认为值得记住使用write_canonical 引擎盖下的样子:

    +(+(+(3.0,*(0.5,x1)),*(0.6,x2)),*(0.7,x3))
    

    遍历多项式应该只涉及几个简单的情况;以下可能实际上是矫枉过正:

    coefficient(X=Y, Var, Coeff) :-
        coefficient(X, Var, Coeff) ; coefficient(Y, Var, Coeff).
    coefficient(X+Y, Var, Coeff) :-
        coefficient(X, Var, Coeff) ; coefficient(Y, Var, Coeff).
    coefficient(X-Y, Var, Coeff) :-
        coefficient(X, Var, Coeff) ; coefficient(Y, Var, Coeff).
    coefficient(X*Y, X, Y) :-
        atomic(X), atomic(Y).
    coefficient(X*Y, Var, Coeff) :-
        coefficient(X, Var, Coeff) ; coefficient(Y, Var, Coeff).
    

    您的基本情况确实是 X*Y 情况,它们都是原子的。其余的子句实际上只是为了展开嵌套。这似乎可以满足您的要求:

    ?- relation(independents([var(x1,X1),var(x2,X2),var(x3,X3)]),
                dependent(var(y,Y))), 
       dump([X1,X2,X3,Y],[x1,x2,x3,y], [y=Eqn]), 
       coefficient(Eqn, Var, Coeff).
    
    Eqn = 3.0+0.5*x1+0.6*x2+0.7*x3,
    Var = 0.5,
    Coeff = x1,
    {Y=3.0+0.5*X1+0.6*X2+0.7*X3} ;
    Eqn = 3.0+0.5*x1+0.6*x2+0.7*x3,
    Var = 0.6,
    Coeff = x2,
    {Y=3.0+0.5*X1+0.6*X2+0.7*X3} ;
    Eqn = 3.0+0.5*x1+0.6*x2+0.7*x3,
    Var = 0.7,
    Coeff = x3,
    {Y=3.0+0.5*X1+0.6*X2+0.7*X3} ;
    false.
    

    要真正概括这一点,您可能需要使用maplist 等。人。要将您的独立/受抚养人列表转换为您需要传递给dump/3 的变量,然后处理结果中有多个方程式的情况,但我认为这对您来说不会很有挑战性。

    希望这会有所帮助!

    【讨论】:

    • 非常感谢您的回复!我非常感谢您以这种方式分享您的专业知识。鉴于我的问题,我认为这是要走的路。
    • @JCR 很高兴能为您提供帮助,希望您喜欢在 Prolog 中处理您的项目!
    猜你喜欢
    • 2011-02-06
    • 2020-10-16
    • 1970-01-01
    • 1970-01-01
    • 2016-08-13
    • 2015-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多