|
| 1 | +/** |
| 2 | + * Prolog code for the polynominal reduction benchmark. |
| 3 | + * |
| 4 | + * This benchmark can be found in: |
| 5 | + * Haygood, R. (1989): A Prolog Benchmark Suite for Aquarius, |
| 6 | + * Computer Science Division, University of California |
| 7 | + * Berkely, April 30, 1989 |
| 8 | + * |
| 9 | + * It has its root in some Lisp code by R.P. Gabriel. |
| 10 | + * |
| 11 | + * We used a brushed up version where polynomials are better |
| 12 | + * normalized. Therefore we find some additional predicates |
| 13 | + * such as make_poly/3 and make_term/4. |
| 14 | + * |
| 15 | + * Warranty & Liability |
| 16 | + * To the extent permitted by applicable law and unless explicitly |
| 17 | + * otherwise agreed upon, XLOG Technologies GmbH makes no warranties |
| 18 | + * regarding the provided information. XLOG Technologies GmbH assumes |
| 19 | + * no liability that any problems might be solved with the information |
| 20 | + * provided by XLOG Technologies GmbH. |
| 21 | + * |
| 22 | + * Rights & License |
| 23 | + * All industrial property rights regarding the information - copyright |
| 24 | + * and patent rights in particular - are the sole property of XLOG |
| 25 | + * Technologies GmbH. If the company was not the originator of some |
| 26 | + * excerpts, XLOG Technologies GmbH has at least obtained the right to |
| 27 | + * reproduce, change and translate the information. |
| 28 | + * |
| 29 | + * Reproduction is restricted to the whole unaltered document. Reproduction |
| 30 | + * of the information is only allowed for non-commercial uses. Selling, |
| 31 | + * giving away or letting of the execution of the library is prohibited. |
| 32 | + * The library can be distributed as part of your applications and libraries |
| 33 | + * for execution provided this comment remains unchanged. |
| 34 | + * |
| 35 | + * Trademarks |
| 36 | + * Jekejeke is a registered trademark of XLOG Technologies GmbH. |
| 37 | + */ |
| 38 | + |
| 39 | +/*****************************************************************/ |
| 40 | +/* Normal Test Cases */ |
| 41 | +/*****************************************************************/ |
| 42 | + |
| 43 | +% poly |
| 44 | +poly :- |
| 45 | + poly_add(1, poly(x,[term(1,-1)]), X1), |
| 46 | + poly_add(X1, poly(y,[term(1,1)]), X2), |
| 47 | + poly_add(X2, poly(z,[term(1,-1)]), X3), |
| 48 | + poly_exp(10, X3, _). |
| 49 | + |
| 50 | +/*****************************************************************/ |
| 51 | +/* Reduced Test Cases */ |
| 52 | +/*****************************************************************/ |
| 53 | + |
| 54 | +% rpoly |
| 55 | +rpoly :- |
| 56 | + poly_add(1, poly(x,[term(1,-1)]), X1), |
| 57 | + poly_add(X1, poly(y,[term(1,1)]), X2), |
| 58 | + poly_exp(10, X2, _). |
| 59 | + |
| 60 | +/*****************************************************************/ |
| 61 | +/* The Simplifier */ |
| 62 | +/*****************************************************************/ |
| 63 | + |
| 64 | +% make_poly(+Sum, +Var, -Expr) |
| 65 | +make_poly([], _, 0) :- !. |
| 66 | +make_poly(Terms, Var, poly(Var,Terms)). |
| 67 | + |
| 68 | +% poly_add(+Expr, +Expr, -Expr) |
| 69 | +poly_add(poly(Var,Terms1), poly(Var,Terms2), Res) :- !, |
| 70 | + term_add(Terms1, Terms2, Terms), |
| 71 | + make_poly(Terms, Var, Res). |
| 72 | +poly_add(poly(Var1,Terms1), poly(Var2,Terms2), poly(Var1,Terms)) :- |
| 73 | + Var1 @< Var2, !, |
| 74 | + add_to_order_zero_term(Terms1, poly(Var2,Terms2), Terms). |
| 75 | +poly_add(Poly, poly(Var,Terms2), poly(Var,Terms)) :- !, |
| 76 | + add_to_order_zero_term(Terms2, Poly, Terms). |
| 77 | +poly_add(poly(Var,Terms1), C, poly(Var,Terms)) :- !, |
| 78 | + add_to_order_zero_term(Terms1, C, Terms). |
| 79 | +poly_add(C1, C2, C) :- |
| 80 | + C is C1+C2. |
| 81 | + |
| 82 | +% make_term(+Expr, +Integer, +Sum, -Sum) |
| 83 | +make_term(0, _, Terms, Terms) :- !. |
| 84 | +make_term(C, E, Terms, [term(E,C)|Terms]). |
| 85 | + |
| 86 | +% term_add(+Sum, +Sum, -Sum) |
| 87 | +term_add([], X, X) :- !. |
| 88 | +term_add(X, [], X) :- !. |
| 89 | +term_add([term(E,C1)|Terms1], [term(E,C2)|Terms2], Res) :- !, |
| 90 | + poly_add(C1, C2, C), |
| 91 | + term_add(Terms1, Terms2, Terms), |
| 92 | + make_term(C, E, Terms, Res). |
| 93 | +term_add([term(E1,C1)|Terms1], [term(E2,C2)|Terms2], [term(E1,C1)|Terms]) :- |
| 94 | + E1 < E2, !, |
| 95 | + term_add(Terms1, [term(E2,C2)|Terms2], Terms). |
| 96 | +term_add(Terms1, [term(E2,C2)|Terms2], [term(E2,C2)|Terms]) :- |
| 97 | + term_add(Terms1, Terms2, Terms). |
| 98 | + |
| 99 | +% add_to_order_zero_term(+Sum, +Expr, -Sum) |
| 100 | +add_to_order_zero_term([term(0,C1)|Terms], C2, [term(0,C)|Terms]) :- !, |
| 101 | + poly_add(C1, C2, C). |
| 102 | +add_to_order_zero_term(Terms, C, [term(0,C)|Terms]). |
| 103 | + |
| 104 | +% poly_mul(+Expr, +Expr, -Expr) |
| 105 | +poly_mul(poly(Var,Terms1), poly(Var,Terms2), poly(Var,Terms)) :- !, |
| 106 | + term_mul(Terms1, Terms2, Terms). |
| 107 | +poly_mul(poly(Var1,Terms1), poly(Var2,Terms2), poly(Var1,Terms)) :- |
| 108 | + Var1 @< Var2, !, |
| 109 | + mul_through(Terms1, poly(Var2,Terms2), Terms). |
| 110 | +poly_mul(P, poly(Var,Terms2), Res) :- !, |
| 111 | + mul_through(Terms2, P, Terms), |
| 112 | + make_poly(Terms, Var, Res). |
| 113 | +poly_mul(poly(Var,Terms1), C, Res) :- !, |
| 114 | + mul_through(Terms1, C, Terms), |
| 115 | + make_poly(Terms, Var, Res). |
| 116 | +poly_mul(C1, C2, C) :- |
| 117 | + C is C1*C2. |
| 118 | + |
| 119 | +% term_mul(+Sum, +Sum, -Sum) |
| 120 | +term_mul([], _, []) :- !. |
| 121 | +term_mul(_, [], []) :- !. |
| 122 | +term_mul([Term|Terms1], Terms2, Terms) :- |
| 123 | + single_term_mul(Terms2, Term, PartA), |
| 124 | + term_mul(Terms1, Terms2, PartB), |
| 125 | + term_add(PartA, PartB, Terms). |
| 126 | + |
| 127 | +% single_term_mul(+Sum, +Summand, -Sum) |
| 128 | +single_term_mul([], _, []). |
| 129 | +single_term_mul([term(E1,C1)|Terms1], term(E2,C2), [term(E,C)|Terms]) :- |
| 130 | + E is E1+E2, |
| 131 | + poly_mul(C1, C2, C), |
| 132 | + single_term_mul(Terms1, term(E2,C2), Terms). |
| 133 | + |
| 134 | +% mul_through(+Sum, +Expr, -Sum) |
| 135 | +mul_through([], _, []). |
| 136 | +mul_through([term(E,Term)|Terms], Poly, Res) :- |
| 137 | + poly_mul(Term, Poly, NewTerm), |
| 138 | + mul_through(Terms, Poly, NewTerms), |
| 139 | + make_term(NewTerm, E, NewTerms, Res). |
| 140 | + |
| 141 | +% poly_expr(+Integer, +Expr, -Expr) |
| 142 | +poly_exp(0, _, 1) :- !. |
| 143 | +poly_exp(N, Poly, Result) :- |
| 144 | + N rem 2 =:= 0, !, |
| 145 | + M is N//2, |
| 146 | + poly_exp(M, Poly, Part), |
| 147 | + poly_mul(Part, Part, Result). |
| 148 | +poly_exp(N, Poly, Result) :- |
| 149 | + M is N-1, |
| 150 | + poly_exp(M, Poly, Part), |
| 151 | + poly_mul(Poly, Part, Result). |
0 commit comments