00001 #ifndef VIENNAMATH_MANIPULATION_SIMPLIFY_HPP
00002 #define VIENNAMATH_MANIPULATION_SIMPLIFY_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "viennamath/forwards.h"
00021 #include "viennamath/runtime/functor_wrapper.hpp"
00022 #include <assert.h>
00023
00028 namespace viennamath
00029 {
00030
00031
00032
00033
00034
00035 namespace result_of
00036 {
00037
00038
00039 namespace detail
00040 {
00041
00042
00043 template <typename ExpressionType>
00044 struct simplify_impl
00045 {
00046
00047 enum { value = 0 };
00048 typedef ExpressionType type;
00049 };
00050
00051 template <typename LHS, typename OP, typename RHS>
00052 struct simplify_impl< ct_binary_expr<LHS, OP, RHS> >
00053 {
00054
00055 enum { value = simplify_impl<LHS>::value + simplify_impl<RHS>::value };
00056 typedef ct_binary_expr<typename simplify_impl<LHS>::type,
00057 OP,
00058 typename simplify_impl<RHS>::type
00059 > type;
00060 };
00061
00062
00064
00065
00066 template <typename LHS, typename NumericT>
00067 struct simplify_impl < ct_binary_expr<LHS, op_plus<NumericT>, ct_constant<0> > >
00068 {
00069 enum { value = 1 };
00070 typedef LHS type;
00071 };
00072
00073
00074 template <typename NumericT, typename RHS>
00075 struct simplify_impl < ct_binary_expr<ct_constant<0>, op_plus<NumericT>, RHS> >
00076 {
00077 enum { value = 1 };
00078 typedef RHS type;
00079 };
00080
00081
00082 template <typename NumericT>
00083 struct simplify_impl < ct_binary_expr<ct_constant<0>, op_plus<NumericT>, ct_constant<0> > >
00084 {
00085 enum { value = 1 };
00086 typedef ct_constant<0> type;
00087 };
00088
00089
00090
00091
00093
00094
00095 template <typename LHS, typename NumericT>
00096 struct simplify_impl < ct_binary_expr<LHS, op_minus<NumericT>, ct_constant<0> > >
00097 {
00098 enum { value = 1 };
00099 typedef LHS type;
00100 };
00101
00102
00103 template <typename LHS1, typename NumericT, typename RHS2>
00104 struct simplify_impl < ct_binary_expr<LHS1,
00105 op_plus<NumericT>,
00106 ct_binary_expr<ct_constant<0>,
00107 op_minus<NumericT>,
00108 RHS2 >
00109 > >
00110 {
00111 enum { value = 1 };
00112 typedef ct_binary_expr<LHS1,
00113 op_minus<NumericT>,
00114 RHS2> type;
00115 };
00116
00117 template <typename LHS1, typename NumericT, typename RHS2>
00118 struct simplify_impl < ct_binary_expr<LHS1,
00119 op_minus<NumericT>,
00120 ct_binary_expr<ct_constant<0>,
00121 op_minus<NumericT>,
00122 RHS2 >
00123 > >
00124 {
00125 enum { value = 1 };
00126 typedef ct_binary_expr<LHS1,
00127 op_plus<NumericT>,
00128 RHS2> type;
00129 };
00130
00131 template <typename RHS1, typename NumericT, typename RHS2>
00132 struct simplify_impl < ct_binary_expr<ct_binary_expr< ct_constant<0>,
00133 op_minus<NumericT>,
00134 RHS1 >,
00135 op_plus<NumericT>,
00136 RHS2
00137 > >
00138 {
00139 enum { value = 1 };
00140 typedef ct_binary_expr<RHS2,
00141 op_minus<NumericT>,
00142 RHS1> type;
00143 };
00144
00145 template <typename RHS1, typename NumericT, typename RHS2>
00146 struct simplify_impl < ct_binary_expr<ct_binary_expr< ct_constant<0>,
00147 op_minus<NumericT>,
00148 RHS1 >,
00149 op_minus<NumericT>,
00150 RHS2
00151 > >
00152 {
00153 enum { value = 1 };
00154 typedef ct_binary_expr< ct_constant<-1>,
00155 op_mult<NumericT>,
00156 ct_binary_expr<RHS1,
00157 op_plus<NumericT>,
00158 RHS2>
00159 > type;
00160 };
00161
00162
00163 template <typename RHS1, typename NumericT, typename RHS2>
00164 struct simplify_impl < ct_binary_expr<ct_binary_expr< ct_constant<0>,
00165 op_minus<NumericT>,
00166 RHS1 >,
00167 op_plus<NumericT>,
00168 ct_binary_expr< ct_constant<0>,
00169 op_minus<NumericT>,
00170 RHS2 >
00171 > >
00172 {
00173 enum { value = 1 };
00174 typedef ct_binary_expr< ct_constant<-1>,
00175 op_mult<NumericT>,
00176 ct_binary_expr<RHS1,
00177 op_plus<NumericT>,
00178 RHS2>
00179 > type;
00180 };
00181
00182
00183 template <typename RHS1, typename NumericT, typename RHS2>
00184 struct simplify_impl < ct_binary_expr<ct_binary_expr< ct_constant<0>,
00185 op_minus<NumericT>,
00186 RHS1 >,
00187 op_minus<NumericT>,
00188 ct_binary_expr< ct_constant<0>,
00189 op_minus<NumericT>,
00190 RHS2 >
00191 > >
00192 {
00193 enum { value = 1 };
00194 typedef ct_binary_expr<RHS2,
00195 op_minus<NumericT>,
00196 RHS1> type;
00197 };
00198
00199
00200
00202
00203
00204 template <typename LHS, typename NumericT>
00205 struct simplify_impl < ct_binary_expr<LHS, op_mult<NumericT>, ct_constant<0> > >
00206 {
00207 enum { value = 1 };
00208 typedef ct_constant<0> type;
00209 };
00210
00211
00212 template <typename NumericT, typename RHS>
00213 struct simplify_impl < ct_binary_expr<ct_constant<0>, op_mult<NumericT>, RHS> >
00214 {
00215 enum { value = 1 };
00216 typedef ct_constant<0> type;
00217 };
00218
00219
00220 template <typename NumericT>
00221 struct simplify_impl < ct_binary_expr<ct_constant<0>, op_mult<NumericT>, ct_constant<0> > >
00222 {
00223 enum { value = 1 };
00224 typedef ct_constant<0> type;
00225 };
00226
00227
00229
00230
00231 template <typename LHS, typename NumericT>
00232 struct simplify_impl < ct_binary_expr<LHS, op_mult<NumericT>, ct_constant<1> > >
00233 {
00234 enum { value = 1 };
00235 typedef LHS type;
00236 };
00237
00238
00239 template <typename NumericT, typename RHS>
00240 struct simplify_impl < ct_binary_expr<ct_constant<1>, op_mult<NumericT>, RHS> >
00241 {
00242 enum { value = 1 };
00243 typedef RHS type;
00244 };
00245
00246
00247 template <typename NumericT>
00248 struct simplify_impl < ct_binary_expr<ct_constant<1>, op_mult<NumericT>, ct_constant<1> > >
00249 {
00250 enum { value = 1 };
00251 typedef ct_constant<1> type;
00252 };
00253
00254
00255 template <typename NumericT>
00256 struct simplify_impl < ct_binary_expr<ct_constant<1>, op_mult<NumericT>, ct_constant<0> > >
00257 {
00258 enum { value = 1 };
00259 typedef ct_constant<0> type;
00260 };
00261
00262 template <typename NumericT>
00263 struct simplify_impl < ct_binary_expr<ct_constant<0>, op_mult<NumericT>, ct_constant<1> > >
00264 {
00265 enum { value = 1 };
00266 typedef ct_constant<0> type;
00267 };
00268
00269
00271
00272
00273 template <typename NumericT, typename RHS>
00274 struct simplify_impl < ct_binary_expr<ct_constant<0>, op_div<NumericT>, RHS> >
00275 {
00276 enum { value = 1 };
00277 typedef ct_constant<0> type;
00278 };
00279
00280
00281 template <typename LHS, typename NumericT>
00282 struct simplify_impl < ct_binary_expr<LHS, op_div<NumericT>, ct_constant<0> > >
00283 {
00284 enum { value = 1 };
00285 typedef typename ct_binary_expr<LHS, op_div<NumericT>, ct_constant<0> >::ERROR_ENCOUNTERED_DIVISION_BY_ZERO type;
00286 };
00287
00288
00289
00290 template <typename NumericT>
00291 struct simplify_impl < ct_binary_expr<ct_constant<0>, op_div<NumericT>, ct_constant<0> > >
00292 {
00293 enum { value = 1 };
00294 typedef typename ct_binary_expr<ct_constant<0>, op_div<NumericT>, ct_constant<0> >::ERROR_ENCOUNTERED_DIVISION_BY_ZERO type;
00295 };
00296
00297
00299
00300
00301 template <typename LHS, typename NumericT>
00302 struct simplify_impl < ct_binary_expr<LHS, op_div<NumericT>, ct_constant<1> > >
00303 {
00304 enum { value = 1 };
00305 typedef LHS type;
00306 };
00307
00309
00310 template <typename LHS, typename NumericT, typename RHS>
00311 struct simplify_impl < ct_binary_expr<LHS,
00312 op_mult<NumericT>,
00313 ct_binary_expr<ct_constant<1>, op_div<NumericT>, RHS>
00314 > >
00315 {
00316 enum { value = 1 };
00317 typedef ct_binary_expr<LHS,
00318 op_div<NumericT>,
00319 RHS> type;
00320 };
00321
00322 template <typename RHS1, typename NumericT, typename RHS2>
00323 struct simplify_impl < ct_binary_expr<ct_binary_expr<ct_constant<1>, op_div<NumericT>, RHS1>,
00324 op_mult<NumericT>,
00325 RHS2
00326 > >
00327 {
00328 enum { value = 1 };
00329 typedef ct_binary_expr<RHS2,
00330 op_div<NumericT>,
00331 RHS1> type;
00332 };
00333
00334
00335 template <typename RHS1, typename NumericT, typename RHS2>
00336 struct simplify_impl < ct_binary_expr<ct_binary_expr<ct_constant<1>, op_div<NumericT>, RHS1>,
00337 op_mult<NumericT>,
00338 ct_binary_expr<ct_constant<1>, op_div<NumericT>, RHS2>
00339 > >
00340 {
00341 enum { value = 1 };
00342 typedef ct_binary_expr<ct_constant<1>,
00343 op_div<NumericT>,
00344 ct_binary_expr<RHS1, op_mult<NumericT>, RHS2>
00345 > type;
00346 };
00347
00348
00349
00351
00353
00354
00355 template <long numerator_1, long denominator_1, typename NumericT,
00356 long numerator_2, long denominator_2>
00357 struct simplify_impl< ct_binary_expr<ct_binary_expr<ct_constant<numerator_1>,
00358 op_div<NumericT>,
00359 ct_constant<denominator_1> >,
00360 op_plus<NumericT>,
00361 ct_binary_expr<ct_constant<numerator_2>,
00362 op_div<NumericT>,
00363 ct_constant<denominator_2> >
00364 >
00365 >
00366 {
00367 enum { value = 1,
00368 numerator = numerator_1 * denominator_2 + numerator_2 * denominator_1,
00369 denominator = denominator_1 * denominator_2 };
00370
00371
00372 typedef ct_binary_expr< ct_constant< numerator / result_of::gcd<numerator, denominator>::value >,
00373 op_div<NumericT>,
00374 ct_constant<denominator / result_of::gcd<numerator, denominator>::value > > type;
00375 };
00376
00377 template <long value_1, typename NumericT,
00378 long numerator_2, long denominator_2>
00379 struct simplify_impl< ct_binary_expr<ct_constant<value_1>,
00380 op_plus<NumericT>,
00381 ct_binary_expr<ct_constant<numerator_2>,
00382 op_div<NumericT>,
00383 ct_constant<denominator_2> >
00384 >
00385 >
00386 {
00387 enum { value = 1,
00388 numerator = value_1 * denominator_2 + numerator_2,
00389 denominator = denominator_2 };
00390
00391 typedef ct_binary_expr< ct_constant< numerator / result_of::gcd<numerator, denominator>::value >,
00392 op_div<NumericT>,
00393 ct_constant<denominator / result_of::gcd<numerator, denominator>::value > > type;
00394 };
00395
00396 template <long numerator_1, long denominator_1, typename NumericT,
00397 long value_2>
00398 struct simplify_impl< ct_binary_expr<ct_binary_expr<ct_constant<numerator_1>,
00399 op_div<NumericT>,
00400 ct_constant<denominator_1> >,
00401 op_plus<NumericT>,
00402 ct_constant<value_2>
00403 >
00404 >
00405 {
00406 enum { value = 1,
00407 numerator = numerator_1 + value_2 * denominator_1,
00408 denominator = denominator_1 };
00409
00410 typedef ct_binary_expr< ct_constant< numerator / result_of::gcd<numerator, denominator>::value >,
00411 op_div<NumericT>,
00412 ct_constant<denominator / result_of::gcd<numerator, denominator>::value > > type;
00413 };
00414
00415
00416
00417
00418 template <long numerator_1, long denominator_1, typename NumericT,
00419 long numerator_2, long denominator_2>
00420 struct simplify_impl< ct_binary_expr<ct_binary_expr<ct_constant<numerator_1>,
00421 op_div<NumericT>,
00422 ct_constant<denominator_1> >,
00423 op_minus<NumericT>,
00424 ct_binary_expr<ct_constant<numerator_2>,
00425 op_div<NumericT>,
00426 ct_constant<denominator_2> >
00427 > >
00428 {
00429 enum { value = 1,
00430 numerator = numerator_1 * denominator_2 - numerator_2 * denominator_1,
00431 denominator = denominator_1 * denominator_2 };
00432
00433 typedef ct_binary_expr< ct_constant< numerator / result_of::gcd<numerator, denominator>::value >,
00434 op_div<NumericT>,
00435 ct_constant<denominator / result_of::gcd<numerator, denominator>::value > > type;
00436 };
00437
00438 template <long value_1, typename NumericT,
00439 long numerator_2, long denominator_2>
00440 struct simplify_impl< ct_binary_expr<ct_constant<value_1>,
00441 op_minus<NumericT>,
00442 ct_binary_expr<ct_constant<numerator_2>,
00443 op_div<NumericT>,
00444 ct_constant<denominator_2> >
00445 > >
00446 {
00447 enum { value = 1,
00448 numerator = value_1 * denominator_2 - numerator_2,
00449 denominator = denominator_2 };
00450
00451 typedef ct_binary_expr< ct_constant< numerator / result_of::gcd<numerator, denominator>::value >,
00452 op_div<NumericT>,
00453 ct_constant<denominator / result_of::gcd<numerator, denominator>::value > > type;
00454 };
00455
00456 template <long numerator_1, long denominator_1, typename NumericT,
00457 long value_2>
00458 struct simplify_impl< ct_binary_expr<ct_binary_expr<ct_constant<numerator_1>,
00459 op_div<NumericT>,
00460 ct_constant<denominator_1> >,
00461 op_minus<NumericT>,
00462 ct_constant<value_2>
00463 > >
00464 {
00465 enum { value = 1,
00466 numerator = numerator_1 - value_2 * denominator_1,
00467 denominator = denominator_1 };
00468
00469 typedef ct_binary_expr< ct_constant< numerator / result_of::gcd<numerator, denominator>::value >,
00470 op_div<NumericT>,
00471 ct_constant<denominator / result_of::gcd<numerator, denominator>::value > > type;
00472 };
00473
00474
00475 template <long numerator_1, long denominator_1, typename NumericT>
00476 struct simplify_impl< ct_binary_expr<ct_binary_expr<ct_constant<numerator_1>,
00477 op_div<NumericT>,
00478 ct_constant<denominator_1> >,
00479 op_minus<NumericT>,
00480 ct_constant<0>
00481 > >
00482 {
00483 enum { value = 1,
00484 numerator = numerator_1,
00485 denominator = denominator_1 };
00486
00487 typedef ct_binary_expr< ct_constant< numerator / result_of::gcd<numerator, denominator>::value >,
00488 op_div<NumericT>,
00489 ct_constant<denominator / result_of::gcd<numerator, denominator>::value > > type;
00490 };
00491
00492
00493
00494 template <long numerator_1, long denominator_1, typename NumericT,
00495 long numerator_2, long denominator_2>
00496 struct simplify_impl< ct_binary_expr<ct_binary_expr<ct_constant<numerator_1>,
00497 op_div<NumericT>,
00498 ct_constant<denominator_1> >,
00499 op_mult<NumericT>,
00500 ct_binary_expr<ct_constant<numerator_2>,
00501 op_div<NumericT>,
00502 ct_constant<denominator_2> >
00503 > >
00504 {
00505 enum { value = 1,
00506 numerator = numerator_1 * numerator_2,
00507 denominator = denominator_1 * denominator_2 };
00508
00509 typedef ct_binary_expr< ct_constant< numerator / result_of::gcd<numerator, denominator>::value >,
00510 op_div<NumericT>,
00511 ct_constant<denominator / result_of::gcd<numerator, denominator>::value > > type;
00512 };
00513
00514 template <long value_1, typename NumericT,
00515 long numerator_2, long denominator_2>
00516 struct simplify_impl< ct_binary_expr<ct_constant<value_1>,
00517 op_mult<NumericT>,
00518 ct_binary_expr<ct_constant<numerator_2>,
00519 op_div<NumericT>,
00520 ct_constant<denominator_2> >
00521 > >
00522 {
00523 enum { value = 1,
00524 numerator = value_1 * numerator_2,
00525 denominator = denominator_2 };
00526
00527 typedef ct_binary_expr< ct_constant< numerator / result_of::gcd<numerator, denominator>::value >,
00528 op_div<NumericT>,
00529 ct_constant<denominator / result_of::gcd<numerator, denominator>::value > > type;
00530 };
00531
00532 template <long numerator_1, long denominator_1, typename NumericT,
00533 long value_2>
00534 struct simplify_impl< ct_binary_expr<ct_binary_expr<ct_constant<numerator_1>,
00535 op_div<NumericT>,
00536 ct_constant<denominator_1> >,
00537 op_mult<NumericT>,
00538 ct_constant<value_2>
00539 > >
00540 {
00541 enum { value = 1,
00542 numerator = numerator_1 * value_2,
00543 denominator = denominator_1 };
00544
00545 typedef ct_binary_expr< ct_constant< numerator / result_of::gcd<numerator, denominator>::value >,
00546 op_div<NumericT>,
00547 ct_constant<denominator / result_of::gcd<numerator, denominator>::value > > type;
00548 };
00549
00550
00551 template <long numerator_1, long denominator_1, typename NumericT,
00552 long numerator_2, long denominator_2>
00553 struct simplify_impl< ct_binary_expr<ct_binary_expr<ct_constant<numerator_1>,
00554 op_div<NumericT>,
00555 ct_constant<denominator_1> >,
00556 op_div<NumericT>,
00557 ct_binary_expr<ct_constant<numerator_2>,
00558 op_div<NumericT>,
00559 ct_constant<denominator_2> >
00560 > >
00561 {
00562 enum { value = 1,
00563 numerator = numerator_1 * denominator_2,
00564 denominator = denominator_1 * numerator_2 };
00565
00566 typedef ct_binary_expr< ct_constant< numerator / result_of::gcd<numerator, denominator>::value >,
00567 op_div<NumericT>,
00568 ct_constant<denominator / result_of::gcd<numerator, denominator>::value > > type;
00569 };
00570
00571 template <long value_1, typename NumericT,
00572 long numerator_2, long denominator_2>
00573 struct simplify_impl< ct_binary_expr<ct_constant<value_1>,
00574 op_div<NumericT>,
00575 ct_binary_expr<ct_constant<numerator_2>,
00576 op_div<NumericT>,
00577 ct_constant<denominator_2> >
00578 > >
00579 {
00580 enum { value = 1,
00581 numerator = value_1 * denominator_2,
00582 denominator = numerator_2 };
00583
00584 typedef ct_binary_expr< ct_constant< numerator / result_of::gcd<numerator, denominator>::value >,
00585 op_div<NumericT>,
00586 ct_constant<denominator / result_of::gcd<numerator, denominator>::value > > type;
00587 };
00588
00589 template <long numerator_1, typename NumericT, long denominator_1,
00590 long value_2>
00591 struct simplify_impl< ct_binary_expr<ct_binary_expr<ct_constant<numerator_1>,
00592 op_div<NumericT>,
00593 ct_constant<denominator_1> >,
00594 op_div<NumericT>,
00595 ct_constant<value_2>
00596 > >
00597 {
00598 enum { value = 1,
00599 numerator = numerator_1,
00600 denominator = denominator_1 * value_2 };
00601
00602 typedef ct_binary_expr< ct_constant< numerator / result_of::gcd<numerator, denominator>::value >,
00603 op_div<NumericT>,
00604 ct_constant<denominator / result_of::gcd<numerator, denominator>::value > > type;
00605 };
00606
00607
00608 template <long value_1, typename NumericT, long value_2>
00609 struct simplify_impl< ct_binary_expr<ct_constant<value_1>,
00610 op_plus<NumericT>,
00611 ct_constant<value_2>
00612 > >
00613 {
00614 enum { value = 1 };
00615 typedef ct_constant<value_1 + value_2> type;
00616 };
00617
00618 template <long value_1, typename NumericT>
00619 struct simplify_impl< ct_binary_expr<ct_constant<value_1>,
00620 op_plus<NumericT>,
00621 ct_constant<0>
00622 > >
00623 {
00624 enum { value = 1 };
00625 typedef ct_constant<value_1> type;
00626 };
00627
00628 template <typename NumericT, long value_2>
00629 struct simplify_impl< ct_binary_expr<ct_constant<0>,
00630 op_plus<NumericT>,
00631 ct_constant<value_2>
00632 > >
00633 {
00634 enum { value = 1 };
00635 typedef ct_constant<value_2> type;
00636 };
00637
00638 template <long value_1, typename NumericT, long value_2>
00639 struct simplify_impl< ct_binary_expr<ct_constant<value_1>,
00640 op_minus<NumericT>,
00641 ct_constant<value_2>
00642 > >
00643 {
00644 enum { value = 1 };
00645 typedef ct_constant<value_1 - value_2> type;
00646 };
00647
00648
00649 template <typename NumericT>
00650 struct simplify_impl< ct_binary_expr<ct_constant<1>,
00651 op_minus<NumericT>,
00652 ct_constant<0>
00653 > >
00654 {
00655 enum { value = 1 };
00656 typedef ct_constant<1> type;
00657 };
00658
00659 template <typename NumericT>
00660 struct simplify_impl< ct_binary_expr<ct_constant<-1>,
00661 op_minus<NumericT>,
00662 ct_constant<0>
00663 > >
00664 {
00665 enum { value = 1 };
00666 typedef ct_constant<-1> type;
00667 };
00668
00669
00671
00672 template <long value_1, typename NumericT, long value_2>
00673 struct simplify_impl< ct_binary_expr<ct_constant<value_1>,
00674 op_mult<NumericT>,
00675 ct_constant<value_2>
00676 > >
00677 {
00678 enum { value = 1 };
00679 typedef ct_constant<value_1 * value_2> type;
00680 };
00681
00682
00683 template <typename NumericT, long value_2>
00684 struct simplify_impl< ct_binary_expr<ct_constant<1>,
00685 op_mult<NumericT>,
00686 ct_constant<value_2>
00687 > >
00688 {
00689 enum { value = 1 };
00690 typedef ct_constant<value_2> type;
00691 };
00692
00693 template <long value_1, typename NumericT>
00694 struct simplify_impl< ct_binary_expr<ct_constant<value_1>,
00695 op_mult<NumericT>,
00696 ct_constant<1>
00697 > >
00698 {
00699 enum { value = 1 };
00700 typedef ct_constant<value_1> type;
00701 };
00702
00703 template <long value_1, typename NumericT>
00704 struct simplify_impl< ct_binary_expr<ct_constant<value_1>,
00705 op_mult<NumericT>,
00706 ct_constant<0>
00707 > >
00708 {
00709 enum { value = 1 };
00710 typedef ct_constant<0> type;
00711 };
00712
00713 template <typename NumericT, long value_2>
00714 struct simplify_impl< ct_binary_expr<ct_constant<0>,
00715 op_mult<NumericT>,
00716 ct_constant<value_2>
00717 > >
00718 {
00719 enum { value = 1 };
00720 typedef ct_constant<0> type;
00721 };
00722
00723
00724
00725
00726
00727 template <long value_1, typename NumericT, long value_2>
00728 struct simplify_impl< ct_binary_expr<ct_constant<value_1>,
00729 op_div<NumericT>,
00730 ct_constant<value_2>
00731 > >
00732 {
00733 enum { value = 0 };
00734 typedef ct_binary_expr<ct_constant<value_1 / result_of::gcd<value_1, value_2>::value >,
00735 op_div<NumericT>,
00736 ct_constant<value_2 / result_of::gcd<value_1, value_2>::value >
00737 > type;
00738 };
00739
00740 template <typename NumericT, long value_2>
00741 struct simplify_impl< ct_binary_expr<ct_constant<0>,
00742 op_div<NumericT>,
00743 ct_constant<value_2>
00744 > >
00745 {
00746 enum { value = 1 };
00747 typedef ct_constant<0> type;
00748 };
00749
00750 template <typename NumericT>
00751 struct simplify_impl< ct_binary_expr<ct_constant<0>,
00752 op_div<NumericT>,
00753 ct_constant<1>
00754 > >
00755 {
00756 enum { value = 1 };
00757 typedef ct_constant<0> type;
00758 };
00759
00760 template <long value_1, typename NumericT>
00761 struct simplify_impl< ct_binary_expr<ct_constant<value_1>,
00762 op_div<NumericT>,
00763 ct_constant<1>
00764 > >
00765 {
00766 enum { value = 1 };
00767 typedef ct_constant<value_1> type;
00768 };
00769
00770
00771 template <long value_1, typename NumericT>
00772 struct simplify_impl< ct_binary_expr<ct_constant<value_1>,
00773 op_div<NumericT>,
00774 ct_constant<-1>
00775 > >
00776 {
00777 enum { value = 1 };
00778 typedef ct_constant<-value_1> type;
00779 };
00780
00781
00782 }
00783
00785
00786
00787
00788
00796 template <typename ExpressionType,
00797 bool optimization_possible = (detail::simplify_impl<ExpressionType>::value != 0)
00798 >
00799 struct simplify {};
00800
00801
00803 template <typename LHS, typename OP, typename RHS>
00804 struct simplify < ct_binary_expr<LHS, OP, RHS>, true >
00805 {
00806 typedef typename detail::simplify_impl< ct_binary_expr<LHS, OP, RHS> >::type simplified_type;
00807 typedef typename simplify<simplified_type>::type type;
00808
00809 };
00810
00812 template <typename LHS, typename OP, typename RHS>
00813 struct simplify < ct_binary_expr<LHS, OP, RHS>, false >
00814 {
00815 typedef ct_binary_expr<LHS, OP, RHS> type;
00816 };
00817
00818
00820 template <typename LHS, typename OP>
00821 struct simplify < ct_unary_expr<LHS, OP>, true >
00822 {
00823 typedef typename detail::simplify_impl< ct_unary_expr<LHS, OP> >::type simplified_type;
00824 typedef typename simplify<simplified_type>::type type;
00825 };
00826
00828 template <typename LHS, typename OP>
00829 struct simplify < ct_unary_expr<LHS, OP>, false >
00830 {
00831 typedef ct_unary_expr<LHS, OP> type;
00832 };
00833
00834
00836 template <long value>
00837 struct simplify < ct_constant<value>, true >
00838 {
00839 typedef typename detail::simplify_impl< ct_constant<value> >::type simplified_type;
00840 typedef typename simplify<simplified_type>::type type;
00841 };
00842
00844 template <long value>
00845 struct simplify < ct_constant<value>, false >
00846 {
00847 typedef ct_constant<value> type;
00848 };
00849
00850
00852 template <typename TAG>
00853 struct simplify < ct_function_symbol<TAG>, true >
00854 {
00855 typedef typename detail::simplify_impl< ct_function_symbol<TAG> >::type simplified_type;
00856 typedef typename simplify<simplified_type>::type type;
00857 };
00858
00860 template <typename TAG>
00861 struct simplify < ct_function_symbol<TAG>, false >
00862 {
00863 typedef ct_function_symbol<TAG> type;
00864 };
00865
00866
00868 template <id_type id>
00869 struct simplify < ct_variable<id>, true >
00870 {
00871 typedef typename detail::simplify_impl< ct_variable<id> >::type simplified_type;
00872 typedef typename simplify<simplified_type>::type type;
00873 };
00874
00876 template <id_type id>
00877 struct simplify < ct_variable<id>, false >
00878 {
00879 typedef ct_variable<id> type;
00880 };
00881
00882 }
00883
00884
00886 template <typename ExpressionType>
00887 typename result_of::simplify<ExpressionType>::type
00888 simplify(ExpressionType const & e)
00889 {
00890 return typename result_of::simplify<ExpressionType>::type();
00891 }
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00905 template <typename InterfaceType>
00906 void inplace_simplify(rt_expr<InterfaceType> & e)
00907 {
00908 while (e.get()->can_simplify())
00909 e = e.get()->simplify();
00910 }
00911
00913 template <typename InterfaceType>
00914 void inplace_simplify(rt_unary_expr<InterfaceType> & e)
00915 {
00916 while (e->can_simplify())
00917 e = e->simplify();
00918 }
00919
00921 template <typename InterfaceType>
00922 void inplace_simplify(rt_binary_expr<InterfaceType> & e)
00923 {
00924 while (e->can_simplify())
00925 e = e->simplify();
00926 }
00927
00929 template <typename T>
00930 void inplace_simplify(T & e)
00931 {
00932
00933 }
00934
00935
00936
00938 template <typename InterfaceType>
00939 rt_expr<InterfaceType> simplify(rt_expr<InterfaceType> const & e)
00940 {
00941 rt_expr<InterfaceType> ret(e);
00942 inplace_simplify(ret);
00943 return ret;
00944 }
00945
00947 template <typename InterfaceType>
00948 rt_expr<InterfaceType> simplify(rt_unary_expr<InterfaceType> const & e)
00949 {
00950 rt_expr<InterfaceType> ret(e);
00951 inplace_simplify(ret);
00952 return ret;
00953 }
00954
00956 template <typename InterfaceType>
00957 rt_expr<InterfaceType> simplify(rt_binary_expr<InterfaceType> const & e)
00958 {
00959 rt_expr<InterfaceType> ret(e);
00960 inplace_simplify(ret);
00961 return ret;
00962 }
00963
00965 template <typename T>
00966 T simplify(T const & e)
00967 {
00968
00969 return e;
00970 }
00971
00972 }
00973
00974 #endif