我想构建一个简单的prolog代码

时间:2016-05-24 13:53:19

标签: prolog

您好我想构建一个简单的prolog代码,显示多项式

例如if            查询:polynomial([exponent(A1,A2),exponent(B1,B2),exponent(X1,0)])

显示A1X^A2 + B1X^B2 + X1

谁能帮助我?

1 个答案:

答案 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 ?- 

希望这有帮助