在数值表达式(clpr)中访问系数

时间:2019-02-21 14:33:29

标签: prolog clpr

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

:-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}.

是否有一种直接(间接)获得该方程式系数的方法?即返回coefficient(VARNAME, COEFFICIENT)的规则,例如coefficient(x1, 0.5), coefficient(x2, 0.6),依此类推。

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

我当前的解决方案是一个复杂且模糊的解决方案,涉及member/2subtract/3maplist/2,并将X1,X2,X3设置为1或零以找出每个斜率。

相关问题: Representing linear functions in prolog

谢谢!

/ JC

1 个答案:

答案 0 :(得分:2)

这是我第一次使用mocha-serverless-plugin,因此,如果这对您无济于事,我恳求精神错乱,但对我来说,这里的关键似乎是使用clpr将约束转换回Prolog表达式然后像其他任何结构一样遍历它。因此,我通过执行以下操作再次获得了约束:

dump/3

我认为值得用?- 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))

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

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).

要真正概括这一点,您可能需要使用?- 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,然后处理结果中包含多个方程的情况,但是我认为这对您来说并不具有挑战性。 / p>

希望这会有所帮助!