![]() |
libsesstype
2.0.0
Library for Session Types programming.
|
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__