libsesstype  2.0.0
Library for Session Types programming.
expr_invert.h
00001 #ifndef SESSTYPE__PARAMETERISED__UTIL__EXPR_INVERT_H__
00002 #define SESSTYPE__PARAMETERISED__UTIL__EXPR_INVERT_H__
00003 
00004 #ifdef __cplusplus
00005 #include <stack>
00006 #endif
00007 
00008 #include "sesstype/parameterised/expr.h"
00009 #include "sesstype/parameterised/expr/var.h"
00010 #include "sesstype/parameterised/expr/val.h"
00011 #include "sesstype/parameterised/expr/add.h"
00012 #include "sesstype/parameterised/expr/sub.h"
00013 #include "sesstype/parameterised/expr/mul.h"
00014 #include "sesstype/parameterised/expr/div.h"
00015 #include "sesstype/parameterised/expr/mod.h"
00016 #include "sesstype/parameterised/expr/shl.h"
00017 #include "sesstype/parameterised/expr/shr.h"
00018 #include "sesstype/parameterised/expr/seq.h"
00019 #include "sesstype/parameterised/expr/rng.h"
00020 #include "sesstype/parameterised/expr/log.h"
00021 #include "sesstype/parameterised/util/expr_visitor.h"
00022 
00023 #ifdef __cplusplus
00024 namespace sesstype {
00025 namespace parameterised {
00026 namespace util {
00027 #endif
00028 
00029 #ifdef __cplusplus
00030 
00036 class ExprInvert : public ExprVisitor {
00037     bool error_;
00038     Expr *reversed_;
00039     std::string var_;
00040 
00041   public:
00042     ExprInvert(std::string var) : error_(false),
00043                                   reversed_(new VarExpr(var)),
00044                                   var_(var) { }
00045 
00046     Expr *invert()
00047     {
00048         if (is_valid()) {
00049             return reversed_;
00050         }
00051         return nullptr;
00052     }
00053 
00054     bool is_valid()
00055     {
00056         return !error_;
00057     }
00058 
00059     bool has_var(Expr *expr)
00060     {
00061         if (auto vare = dynamic_cast<VarExpr *>(expr)) {
00062             return (vare->name() == var_);
00063         } else if (auto bine = dynamic_cast<BinExpr *>(expr)) {
00064             return ( has_var(bine->lhs()) || has_var(bine->rhs()) );
00065         }
00066         return false;
00067     }
00068 
00069     virtual void visit(Expr *expr) override
00070     {
00071         // Nothing.
00072     }
00073 
00074     virtual void visit(VarExpr *expr) override
00075     {
00076     }
00077 
00078     virtual void visit(ValExpr *expr) override
00079     {
00080     }
00081 
00082     virtual void visit(AddExpr *expr) override
00083     {
00084         if (has_var(expr->lhs())) { // x + a = y --> x = y - a
00085             reversed_ = new SubExpr(reversed_, expr->rhs()->clone());
00086             expr->lhs()->accept(*this);
00087             return;
00088         }
00089 
00090         if (has_var(expr->rhs())) { // a + x = y --> x = y - a
00091             reversed_ = new SubExpr(reversed_, expr->lhs()->clone());
00092             expr->rhs()->accept(*this);
00093             return;
00094         }
00095 
00096         error_ = true;
00097     }
00098 
00099     virtual void visit(SubExpr *expr) override
00100     {
00101         if (has_var(expr->lhs())) { // x - a = y --> x = y + a
00102             reversed_ = new AddExpr(reversed_, expr->rhs()->clone());
00103             expr->lhs()->accept(*this);
00104             return;
00105         }
00106 
00107         if (has_var(expr->rhs())) { // a - x = y --> x = a - y
00108             reversed_ = new SubExpr(expr->lhs()->clone(), reversed_);
00109             expr->rhs()->accept(*this);
00110             return;
00111         }
00112 
00113         error_ = true;
00114     }
00115 
00116     virtual void visit(MulExpr *expr) override
00117     {
00118         if (has_var(expr->lhs())) { // x * a = y --> x = y / a
00119             reversed_ = new DivExpr(reversed_, expr->rhs()->clone());
00120             expr->lhs()->accept(*this);
00121             return;
00122         }
00123 
00124         if (has_var(expr->rhs())) { // a * x = y --> x = y / a
00125             reversed_ = new DivExpr(reversed_, expr->lhs()->clone());
00126             expr->lhs()->accept(*this);
00127             return;
00128         }
00129 
00130         error_ = true;
00131     }
00132 
00133     virtual void visit(DivExpr *expr) override
00134     {
00135         if (has_var(expr->lhs())) { // x / a = y --> x = y * a
00136             reversed_ = new MulExpr(reversed_, expr->rhs()->clone());
00137             expr->lhs()->accept(*this);
00138             return;
00139         }
00140 
00141         if (has_var(expr->rhs())) { // a / x = y --> x = a / y
00142             reversed_ = new DivExpr(expr->lhs()->clone(), reversed_);
00143             expr->rhs()->accept(*this);
00144             return;
00145         }
00146 
00147         error_ = true;
00148     }
00149 
00150     virtual void visit(ModExpr *expr) override
00151     {
00152         // Cannot reverse %
00153         error_ = true;
00154     }
00155 
00156     virtual void visit(ShlExpr *expr) override
00157     {
00158         if (has_var(expr->lhs())) { // x << a = x * 2^a = y --> x = y / (2^a)
00159             reversed_ = new DivExpr(reversed_, new ShlExpr(new ValExpr(1), expr->rhs()->clone()));
00160             expr->lhs()->accept(*this);
00161             return;
00162         }
00163 
00164         if (has_var(expr->rhs())) { // a << x = a * 2^x = y --> log(y / a, 2)
00165             reversed_ = new LogExpr(new DivExpr(reversed_, expr->lhs()->clone()), new ValExpr(2));
00166             expr->rhs()->accept(*this);
00167             return;
00168         }
00169 
00170         error_ = true;
00171     }
00172 
00173     virtual void visit(ShrExpr *expr) override
00174     {
00175         if (has_var(expr->lhs())) { // x << a = x / 2^a = y --> x = y * (2^a)
00176             reversed_ = new DivExpr(reversed_, new ShlExpr(new ValExpr(1), expr->rhs()->clone()));
00177             expr->lhs()->accept(*this);
00178             return;
00179         }
00180 
00181         if (has_var(expr->rhs())) { // a << x = a / 2^x = y --> log(a / y, 2)
00182             reversed_ = new LogExpr(new DivExpr(expr->lhs()->clone(), reversed_), new ValExpr(2));
00183             expr->rhs()->accept(*this);
00184             return;
00185         }
00186 
00187         error_ = true;
00188     }
00189 
00190     virtual void visit(SeqExpr *expr) override
00191     {
00192         error_ = true;
00193     }
00194 
00195     virtual void visit(RngExpr *expr) override
00196     {
00197         error_ = true;
00198     }
00199 
00200     virtual void visit(LogExpr *expr) override
00201     {
00202         reversed_ = new ShlExpr(new ValExpr(1), reversed_);
00203         expr->value()->accept(*this);
00204     }
00205 };
00206 #endif // __cplusplus
00207 
00208 #ifdef __cplusplus
00209 } // namespace util
00210 } // namespace parameterised
00211 } // namespace sesstype
00212 #endif
00213 
00214 #endif//SESSTYPE__PARAMETERISED__UTIL__EXPR_INVERT_H__
 All Classes Namespaces Files Functions