2

我有以下任务:

编写一个将添加两个多项式的方法。即 0+2*x^3 和 0+1*x^3+2*x^4 将给出 0+3*x^3+2*x^4。

我还写了以下代码:

add_poly(+A1*x^B1+P1,+A2*x^B2+P2,+A3*x^B3+P3):-
    (
       B1=B2,
       B3 = B2,
       A3 is A1+A2,
       add_poly(P1,P2,P3)
    ;
       B1<B2,
       B3=B1,
       A3=A1,
       add_poly(P1,+A2*x^B2+P2,P3)
    ;
       B1>B2,
       B3=B2,
       A3=A2,
       add_poly(+A1*x^B1+P1,P2,P3)
    ).
add_poly(X+P1,Y+P2,Z+P3):-
    Z is X+Y,
    add_poly(P1,P2,P3).

我的问题是我不知道如何停止。我想在一个参数为空时停止,而不是将第二个参数附加到第三个参数。但是我如何检查它们是否为空?谢谢。

4

2 回答 2

1

几点说明:

尽量避免(;)/2一开始就出现歧义。它们需要特殊的缩进才能阅读。它们使阅读单个规则变得更加复杂——想想(=)/2你必须编写和跟踪的所有额外目标。


然后,我不确定您可以对多项式做出什么假设。你能假设它们是以规范的形式写成的吗?


对于您的程序:考虑您的第一条规则的主要内容:

add_poly(+A1*x^B1+P1,+A2*x^B2+P2,+A3*x^B3+P3):-

我将概括一些论点:

add_poly(+A1*x^B1+P1,_,_):-

和一些子项:

 add_poly(+_+_,_,_):-

这对应于:

add_poly(+(+(_),_),_,_) :-

不确定你喜欢这个。

因此,此规则仅适用于以前缀+后跟中缀开头的术语+。至少您的示例数据不包含前缀+

另外,请注意 -+运算符是左关联的。这意味着1+2+3+4关联到左侧:

?- write_canonical(1+2+3+4).
+(+(+(1,2),3),4)

因此,如果您有一个术语0+3*x^3+2*x^4,那么您“看到”的第一件事就是_+2*x^4. 左边的术语嵌套得更深。


对于您的实际问题(如何停止) - 您必须明确测试最左边的子项是一个整数,使用integer/1- 或者可能是一个术语 (*)/2 (这取决于您的假设)。

于 2012-07-28T17:49:07.877 回答
1

我假设您所说的多项式在 1 个变量中并且具有整数指数。

这里有一个处理正规多项式形式的过程:多项式可以表示为因子的列表(总和),其中(整数)指数由位置隐式表示。

:- [library(clpfd)].

add_poly(P1, P2, Sum) :-
    normalize(P1, N1),
    normalize(P2, N2),
    append(N1, N2, Nt),
    aggregate_all(max(L), (member(M, Nt), length(M, L)), LMax),
    maplist(rpad(LMax), Nt, Nn),
    clpfd:transpose(Nn, Tn),
    maplist(sumlist, Tn, NSum),
    denormalize(NSum, Sum).

rpad(LMax, List, ListN) :-
    length(List, L),
    D is LMax - L,
    zeros(D, Z),
    append(List, Z, ListN).

% the hardest part is of course normalization: here a draft

normalize(Ts + T, [N|Ns]) :-
    normalize_fact(T, N),
    normalize(Ts, Ns).
normalize(T, [N]) :-
    normalize_fact(T, N).

% build a list with 0s left before position E
normalize_fact(T, Normal) :-
    fact_exp(T, F, E),
    zeros(E, Zeros),
    nth0(E, Normal, F, Zeros).

zeros(E, Zeros) :-
    length(Zeros, E),
    maplist(copy_term(0), Zeros).

fact_exp(F * x ^ E, F, E).
fact_exp(x ^ E, 1, E).
fact_exp(F * x, F, 1).
fact_exp(F, F, 0).

% TBD...
denormalize(NSum, NSum).

测试:

?- add_poly(0+2*x^3, 0+1*x^3+2*x^4, P).
P = [0, 0, 0, 3, 2]

答案仍然是正常形式,应该写 denormalize/2...

于 2012-07-28T20:21:04.577 回答