1 2 package org.lsmp.djep.xjep; 3 import org.nfunk.jep.*; 5 6 25 26 public class SimplificationVisitor extends DoNothingVisitor 27 { 28 private NodeFactory nf; 29 private OperatorSet opSet; 30 private TreeUtils tu; 31 32 public SimplificationVisitor() 33 { 34 } 35 36 37 public Node simplify(Node node,XJep xjep) throws ParseException,IllegalArgumentException 38 { 39 nf = xjep.getNodeFactory(); 40 opSet = xjep.getOperatorSet(); 41 tu = xjep.getTreeUtils(); 42 43 if (node == null) 44 throw new IllegalArgumentException ( 45 "topNode parameter is null"); 46 Node res = (Node) node.jjtAccept(this,null); 47 return res; 48 } 49 50 public Node simplifyBuiltOperatorNode(Operator op,Node lhs,Node rhs) throws ParseException 51 { 52 ASTFunNode res = nf.buildOperatorNode(op,lhs,rhs); 53 Node res2 = simplifyOp(res,new Node[]{lhs,rhs}); 54 return res2; 55 } 56 64 public Node simplifyTripple(XOperator op,Node lhs,Node rhs) throws ParseException 65 { 66 67 XOperator rootOp; 68 if(op.isComposite()) rootOp = (XOperator) op.getRootOp(); 69 else rootOp = op; 70 71 if(op.isCommutative() && tu.isConstant(rhs)) 72 { 73 return simplifyBuiltOperatorNode(op,rhs,lhs); 74 } 75 if(tu.isConstant(lhs) && tu.isBinaryOperator(rhs)) 76 { 77 Node rhsChild1 = rhs.jjtGetChild(0); 78 Node rhsChild2 = rhs.jjtGetChild(1); 79 XOperator rhsOp = (XOperator) ((ASTFunNode) rhs).getOperator(); 80 XOperator rhsRoot; 81 if(rhsOp.isComposite()) rhsRoot = (XOperator) rhsOp.getRootOp(); 82 else rhsRoot = rhsOp; 83 84 if(tu.isConstant(rhsChild1)) 85 { 86 XOperator op2 = (XOperator) rootOp; 87 if(op == rhsOp) op2 = rootOp; 88 else op2 = (XOperator) rootOp.getBinaryInverseOp(); 89 90 if(rootOp == rhsRoot && rootOp.isAssociative()) 92 { 93 Node newnode = simplifyBuiltOperatorNode(op2, 94 nf.buildConstantNode(op,lhs,rhsChild1),rhsChild2); 95 return newnode; 96 } 97 98 if(op.isDistributiveOver(rhsRoot)) { 100 Node newnode = simplifyBuiltOperatorNode(rhsOp, 101 nf.buildConstantNode(op,lhs,rhsChild1), 102 simplifyBuiltOperatorNode(op,lhs,rhsChild2)); 103 return newnode; 104 } 105 } 106 107 108 if(tu.isConstant(rhsChild2)) 109 { 110 112 Operator op2 = rootOp; 113 if(op == rhsOp) op2 = rootOp; 114 else op2 = rootOp.getBinaryInverseOp(); 115 116 if(rootOp == rhsRoot && rootOp.isCommutative() && rootOp.isAssociative()) 117 { 118 Node newnode = simplifyBuiltOperatorNode(op, 119 nf.buildConstantNode(op2,lhs,rhsChild2),rhsChild1); 120 return newnode; 121 } 122 123 if(op.isDistributiveOver(rhsRoot)) { 125 Node newnode = simplifyBuiltOperatorNode(rhsOp, 126 simplifyBuiltOperatorNode(op,lhs,rhsChild1), 127 nf.buildConstantNode(op,lhs,rhsChild2)); 128 return newnode; 129 } 130 } 131 } 132 133 if(tu.isBinaryOperator(lhs) && tu.isConstant(rhs)) 134 { 135 Node lhsChild1 = lhs.jjtGetChild(0); 136 Node lhsChild2 = lhs.jjtGetChild(1); 137 XOperator lhsOp = (XOperator) ((ASTFunNode) lhs).getOperator(); 138 XOperator lhsRoot; 139 if(lhsOp.isComposite()) lhsRoot = (XOperator) lhsOp.getRootOp(); 140 else lhsRoot = (XOperator) lhsOp; 141 142 if(tu.isConstant(lhsChild1)) 143 { 144 if(rootOp == lhsRoot && rootOp.isAssociative() && rootOp.isCommutative()) 146 { 147 Node newnode = simplifyBuiltOperatorNode(lhsOp, 148 nf.buildConstantNode(op,lhsChild1,rhs), 149 lhsChild2); 150 return newnode; 151 } 152 153 if(op.isDistributiveOver(lhsRoot)) 155 { 156 Node newnode = simplifyBuiltOperatorNode(lhsOp, 157 nf.buildConstantNode(op,lhsChild1,rhs), 158 simplifyBuiltOperatorNode(op,lhsChild2,rhs)); 159 return newnode; 160 } 161 } 162 163 164 if(tu.isConstant(lhsChild2)) 165 { 166 if(rootOp == lhsRoot && rootOp.isAssociative()) 170 { 171 Operator op2 = rootOp; 172 if(op == lhsOp) op2 = rootOp; 173 else op2 = rootOp.getBinaryInverseOp(); 174 175 Node newnode = simplifyBuiltOperatorNode(lhsOp, 176 lhsChild1, 177 nf.buildConstantNode(op2,lhsChild2,rhs)); 178 return newnode; 179 } 180 181 if(op.isDistributiveOver(lhsRoot)) 183 { 184 Node newnode = simplifyBuiltOperatorNode(lhsOp, 185 simplifyBuiltOperatorNode(op,lhsChild1,rhs), 186 nf.buildConstantNode(op,lhsChild2,rhs)); 187 return newnode; 188 } 189 } 190 } 191 return null; 192 } 193 194 205 206 public Node simplifyAdd(Node lhs,Node rhs) throws ParseException 207 { 208 if(tu.isInfinity(lhs)) 209 { if(tu.isInfinity(rhs)) 211 return nf.buildConstantNode(tu.getNAN()); 212 else return nf.buildConstantNode(tu.getPositiveInfinity()); 214 } 215 if(tu.isInfinity(rhs)) return nf.buildConstantNode(tu.getPositiveInfinity()); 217 218 if(tu.isZero(lhs)) return rhs; 220 if(tu.isZero(rhs)) return lhs; 222 223 if(tu.isNegative(lhs)) { 225 Node newnode = nf.buildOperatorNode(opSet.getSubtract(), 226 rhs, 227 nf.buildConstantNode(opSet.getUMinus(),lhs)); 228 return newnode; 229 } 230 if(tu.isNegative(rhs)) { 232 Node newnode = nf.buildOperatorNode(opSet.getSubtract(), 233 lhs, 234 nf.buildConstantNode(opSet.getUMinus(),rhs)); 235 return newnode; 236 } 237 return null; 238 } 241 242 254 255 public Node simplifySubtract(Node lhs,Node rhs) throws ParseException 256 { 257 if(tu.isInfinity(lhs)) 258 { if(tu.isInfinity(rhs)) 260 return nf.buildConstantNode(tu.getNAN()); 261 else return nf.buildConstantNode(tu.getPositiveInfinity()); 263 } 264 if(tu.isInfinity(rhs)) return nf.buildConstantNode(tu.getPositiveInfinity()); 266 267 if(tu.isZero(rhs)) return lhs; 269 271 if(tu.isNegative(rhs)) { 273 Node newnode = simplifyBuiltOperatorNode(opSet.getAdd(), 274 lhs, 275 nf.buildConstantNode(opSet.getUMinus(),rhs)); 276 return newnode; 277 } 278 return null; 279 } 282 283 297 298 public Node simplifyMultiply(Node child1,Node child2) throws ParseException 299 { 300 if(tu.isZero(child1)) 301 { if(tu.isInfinity(child2)) 303 return nf.buildConstantNode(tu.getNAN()); 304 else return nf.buildConstantNode(tu.getZERO()); 306 } 307 if(tu.isZero(child2)) 308 { if(tu.isInfinity(child1)) 310 return nf.buildConstantNode(tu.getNAN()); 311 else return nf.buildConstantNode(tu.getZERO()); 313 } 314 if(tu.isInfinity(child1)) return nf.buildConstantNode(tu.getPositiveInfinity()); 316 if(tu.isInfinity(child2)) return nf.buildConstantNode(tu.getPositiveInfinity()); 318 319 if(tu.isOne(child1)) return child2; 321 if(tu.isOne(child2)) return child1; 323 324 if(tu.isMinusOne(child1)) { 326 Node newnode = nf.buildOperatorNode(opSet.getUMinus(),child2); 327 return newnode; 328 } 329 330 if(tu.isMinusOne(child2)) { 332 Node newnode = nf.buildOperatorNode(opSet.getUMinus(),child1); 333 return newnode; 334 } 335 return null; 336 } 339 359 public Node simplifyDivide(Node child1,Node child2) throws ParseException 360 { 361 if(tu.isZero(child2)) 362 { 363 if(tu.isZero(child1)) return nf.buildConstantNode(tu.getNAN()); 365 else return nf.buildConstantNode(tu.getPositiveInfinity()); 367 } 368 369 if(tu.isZero(child1)) 370 { return child1; 372 } 373 if(tu.isOne(child2)) return child1; 377 378 if(tu.isInfinity(child1)) return nf.buildConstantNode(tu.getPositiveInfinity()); 380 if(tu.isInfinity(child2)) return nf.buildConstantNode(tu.getZERO()); 382 return null; 383 } 386 387 396 public Node simplifyPower(Node child1,Node child2) throws ParseException 397 { 398 if(tu.isZero(child1)) 399 { 400 if(tu.isZero(child2)) return nf.buildConstantNode(tu.getNAN()); 402 else return nf.buildConstantNode(tu.getZERO()); 404 } 405 if(tu.isZero(child2)) return nf.buildConstantNode(tu.getONE()); 407 if(tu.isOne(child1)) return nf.buildConstantNode(tu.getONE()); 409 if(tu.isOne(child2)) return child1; 411 412 if(tu.isConstant(child2) && tu.getOperator(child1) == opSet.getPower()) 413 { 414 if(tu.isConstant(child1.jjtGetChild(1))) 415 { 416 417 return nf.buildOperatorNode( 418 opSet.getPower(), 419 child1.jjtGetChild(0), 420 nf.buildConstantNode( 421 opSet.getMultiply(), 422 child1.jjtGetChild(1), 423 child2)); 424 } 425 } 426 return null; 427 } 430 431 432 433 public Node simplifyOp(ASTFunNode node,Node children[]) throws ParseException 434 { 435 boolean allConst=true; 436 XOperator op= (XOperator) node.getOperator(); 437 if(op.getPFMC() instanceof org.nfunk.jep.function.List) return node; 442 int nchild=children.length; 443 for(int i=0;i<nchild;++i) 444 { 445 if(!tu.isConstant(children[i])) 446 allConst=false; 447 if(tu.isNaN(children[i])) 448 return nf.buildConstantNode(tu.getNAN()); 449 } 450 if(allConst) 451 return nf.buildConstantNode(op,children); 452 453 if(nchild==1) 454 { 455 if(tu.isUnaryOperator(children[0]) && op == tu.getOperator(children[0])) 456 { 457 if(op.isSelfInverse()) return children[0].jjtGetChild(0); 458 } 459 } 460 if(nchild==2) 461 { 462 Node res=null; 463 if(opSet.getAdd() == op) res = simplifyAdd(children[0],children[1]); 464 if(opSet.getSubtract() == op) res = simplifySubtract(children[0],children[1]); 465 if(opSet.getMultiply() == op) res = simplifyMultiply(children[0],children[1]); 466 if(opSet.getDivide() == op) res = simplifyDivide(children[0],children[1]); 467 if(opSet.getPower() == op) res = simplifyPower(children[0],children[1]); 468 if(res!=null) 469 { 470 if(tu.isConstant(res)) return res; 471 if(tu.isOperator(res)) 472 { 473 Node res2 = simplifyOp((ASTFunNode) res,TreeUtils.getChildrenAsArray(res)); 474 return res2; 475 } 476 return res; 477 } 478 res = this.simplifyTripple(op,children[0],children[1]); 479 if(res!=null) 480 { 481 if(tu.isConstant(res)) return res; 482 if(tu.isOperator(res)) 483 { 484 Node res2 = simplifyOp((ASTFunNode) res,TreeUtils.getChildrenAsArray(res)); 485 return res2; 486 } 487 return res; 488 } 489 } 490 return node; 491 } 492 493 public Object visit(ASTFunNode node, Object data) throws ParseException 494 { 495 int nchild = node.jjtGetNumChildren(); 496 497 if(node.isOperator()) 498 { 499 XOperator op= (XOperator) node.getOperator(); 500 if( (op.isBinary() && nchild !=2) 501 || (op.isUnary() && nchild !=1)) 502 throw new ParseException("Wrong number of children for "+nchild+" for operator "+op.getName()); 503 504 Node children[] = acceptChildrenAsArray(node,data); 505 TreeUtils.copyChildrenIfNeeded(node,children); 506 507 Node res = simplifyOp(node,children); 508 if(res == null) 509 throw new ParseException("null res from simp op"); 510 return res; 511 } 512 else 513 { 514 Node children[] = acceptChildrenAsArray(node,data); 515 516 boolean allConst=true; 517 for(int i=0;i<nchild;++i) 518 { 519 if(!tu.isConstant(children[i])) 520 allConst=false; 521 if(tu.isNaN(children[i])) 522 return nf.buildConstantNode(tu.getNAN()); 523 } 524 if(allConst) 525 return nf.buildConstantNode(node.getPFMC(),children); 526 527 return TreeUtils.copyChildrenIfNeeded(node,children); 528 } 529 } 530 } 531 | Popular Tags |