您好我想构建一个简单的prolog代码,显示多项式
例如if
查询:polynomial([exponent(A1,A2),exponent(B1,B2),exponent(X1,0)])
显示A1X^A2 + B1X^B2 + X1
答案 0 :(得分:1)
首先,考虑如何输出单个术语,例如......
?- write_term(exponent(x, y)).
......应输出......
x^y
...和...
?- write_term(exponent(x, 0)).
...应该只输出x
。
这个位的代码就是......
% Only need to output base number when exponent is zero
write_term(exponent(X, 0)) :- !,
write(X).
% Otherwise, write X^Y (the 'cut' in the previous rule will stop Prolog searching for alternatives, so once it has matched the pattern exponent(_, 0), it will know to not bother with alternatives)
write_term(exponent(X, Y)) :-
write(X), write('^'), write(Y).
如果您定义上述条款,您现在可以执行...
?- write_term(exponent(x, 2)).
x^2
但是如果你使用变量(以大写字母开头,比如X1),它将不起作用......
4 ?- write_term(exponent(X, 2)).
_G2395^2
因此,您只能使用以小写字母开头的“变量”来实现此目的。
现在您需要点击列表中的每个元素,并使用每个元素调用write_term
...
% Stopping case. Stop when we have an empty list...
poly([]).
% Go through each element calling 'write_term'...
poly([X | T]) :-
write_term(X),
poly(T).
现在,如果你这样做......
?- poly([exponent(a, b), exponent(c, d)]).
......你会得到......
a^bc^d
我们需要打印出一个“加号”符号,这样我们就可以更改第二个poly
条款......
poly([X | T]) :-
write(' + '),
write_term(X),
poly(T).
现在我们得到......
+ a^b + c^d
我们不想输出第一个“加号”符号,因此我们可以向该子句传递一个标志,告诉它它是第一个术语,例如......
poly(X) :-
poly(X, first).
poly([], _).
poly([X | T], IS_FIRST) :-
write_plus_if_not_first(IS_FIRST),
write_term(X),
poly(T, not_first).
第一个规则(poly(X)
)只调用规则的第二个版本,这是第一个元素。
当第一个元素被处理并且poly
规则递归处理列表的其余部分时,它会传递'not_first'作为第二个参数。
新条款write_plus_if_not_first
如果传入first
则无效,否则输出'+'。
write_plus_if_not_first(first) :- !.
% Do nothing case
write_plus_if_not_first(_) :-
% Write a plus sign
write(' + ').
如果你现在打电话给...
?- poly([exponent(a1x, a2), exponent(b1x, b2), exponent(x, 0)]).
......你会得到......
a1x^a2 + b1x^b2 + x
如果您是Prolog的新手,使用trace
可能会帮助您了解正在发生的事情,例如......
1 ?- trace.
true.
[trace] 1 ?- poly([exponent(a1x, a2), exponent(b1x, b2), exponent(x, 0)]).
Call: (6) poly([exponent(a1x, a2), exponent(b1x, b2), exponent(x, 0)]) ? creep
Call: (7) poly([exponent(a1x, a2), exponent(b1x, b2), exponent(x, 0)], first) ? creep
Call: (8) write_plus_if_not_first(first) ? creep
Exit: (8) write_plus_if_not_first(first) ? creep
Call: (8) write_term(exponent(a1x, a2)) ? creep
Call: (9) write(a1x) ? creep
a1x
Exit: (9) write(a1x) ? creep
Call: (9) write(^) ? creep
^
Exit: (9) write(^) ? creep
Call: (9) write(a2) ? creep
a2
Exit: (9) write(a2) ? creep
Exit: (8) write_term(exponent(a1x, a2)) ? creep
Call: (8) poly([exponent(b1x, b2), exponent(x, 0)], not_first) ? creep
Call: (9) write_plus_if_not_first(not_first) ? creep
Call: (10) write(' + ') ? creep
+
Exit: (10) write(' + ') ? creep
Exit: (9) write_plus_if_not_first(not_first) ? creep
Call: (9) write_term(exponent(b1x, b2)) ? creep
Call: (10) write(b1x) ? creep
b1x
Exit: (10) write(b1x) ? creep
Call: (10) write(^) ? creep
^
Exit: (10) write(^) ? creep
Call: (10) write(b2) ? creep
b2
Exit: (10) write(b2) ? creep
Exit: (9) write_term(exponent(b1x, b2)) ? creep
Call: (9) poly([exponent(x, 0)], not_first) ? creep
Call: (10) write_plus_if_not_first(not_first) ? creep
Call: (11) write(' + ') ? creep
+
Exit: (11) write(' + ') ? creep
Exit: (10) write_plus_if_not_first(not_first) ? creep
Call: (10) write_term(exponent(x, 0)) ? creep
Call: (11) write(x) ? creep
x
Exit: (11) write(x) ? creep
Exit: (10) write_term(exponent(x, 0)) ? creep
Call: (10) poly([], not_first) ? creep
Exit: (10) poly([], not_first) ? creep
Exit: (9) poly([exponent(x, 0)], not_first) ? creep
Exit: (8) poly([exponent(b1x, b2), exponent(x, 0)], not_first) ? creep
Exit: (7) poly([exponent(a1x, a2), exponent(b1x, b2), exponent(x, 0)], first) ? creep
Exit: (6) poly([exponent(a1x, a2), exponent(b1x, b2), exponent(x, 0)]) ? creep
true .
[trace] 2 ?-
希望这有帮助