MilesCranmer commited on
Commit
c1c031f
1 Parent(s): c8b410f

Simplify subtraction operation

Browse files
Files changed (1) hide show
  1. julia/sr.jl +73 -20
julia/sr.jl CHANGED
@@ -536,30 +536,83 @@ end
536
 
537
  # Simplify tree
538
  function combineOperators(tree::Node)::Node
539
- # (const (+*) const) already accounted for
540
  # ((const + var) + const) => (const + var)
541
  # ((const * var) * const) => (const * var)
542
- # (anything commutative!)
543
- if tree.degree == 2 && (binops[tree.op] == plus || binops[tree.op] == mult)
 
 
 
 
 
 
 
 
 
 
 
 
544
  op = tree.op
545
- if tree.l.constant || tree.r.constant
546
- # Put the constant in r
547
- if tree.l.constant
548
- tmp = tree.r
549
- tree.r = tree.l
550
- tree.l = tmp
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
551
  end
552
- topconstant = tree.r.val
553
- # Simplify down first
554
- tree.l = combineOperators(tree.l)
555
- below = tree.l
556
- if below.degree == 2 && below.op == op
557
- if below.l.constant
558
- tree = below
559
- tree.l.val = binops[op](tree.l.val, topconstant)
560
- elseif below.r.constant
561
- tree = below
562
- tree.r.val = binops[op](tree.r.val, topconstant)
 
 
 
 
 
 
563
  end
564
  end
565
  end
 
536
 
537
  # Simplify tree
538
  function combineOperators(tree::Node)::Node
539
+ # NOTE: (const (+*-) const) already accounted for. Call simplifyTree before.
540
  # ((const + var) + const) => (const + var)
541
  # ((const * var) * const) => (const * var)
542
+ # ((const - var) - const) => (const - var)
543
+ # (want to add anything commutative!)
544
+ # TODO - need to combine plus/sub if they are both there.
545
+ if tree.degree == 0
546
+ return tree
547
+ elseif tree.degree == 1
548
+ tree.l = combineOperators(tree.l)
549
+ elseif tree.degree == 2
550
+ tree.l = combineOperators(tree.l)
551
+ tree.r = combineOperators(tree.r)
552
+ end
553
+
554
+ top_level_constant = tree.degree == 2 && (tree.l.constant || tree.r.constant)
555
+ if tree.degree == 2 && (binops[tree.op] === mult || binops[tree.op] === plus) && top_level_constant
556
  op = tree.op
557
+ # Put the constant in r
558
+ if tree.l.constant
559
+ tmp = tree.r
560
+ tree.r = tree.l
561
+ tree.l = tmp
562
+ end
563
+ topconstant = tree.r.val
564
+ # Simplify down first
565
+ below = tree.l
566
+ if below.degree == 2 && below.op == op
567
+ if below.l.constant
568
+ tree = below
569
+ tree.l.val = binops[op](tree.l.val, topconstant)
570
+ elseif below.r.constant
571
+ tree = below
572
+ tree.r.val = binops[op](tree.r.val, topconstant)
573
+ end
574
+ end
575
+ end
576
+
577
+ if tree.degree == 2 && binops[tree.op] === sub && top_level_constant
578
+ # Currently just simplifies subtraction. (can't assume both plus and sub are operators)
579
+ # Not commutative, so use different op.
580
+ if tree.l.constant
581
+ if tree.r.degree == 2 && binops[tree.r.op] === sub
582
+ if tree.r.l.constant
583
+ #(const - (const - var)) => (var - const)
584
+ l = tree.l
585
+ r = tree.r
586
+ simplified_const = -(l.val - r.l.val) #neg(sub(l.val, r.l.val))
587
+ tree.l = tree.r.r
588
+ tree.r = l
589
+ tree.r.val = simplified_const
590
+ elseif tree.r.r.constant
591
+ #(const - (var - const)) => (const - var)
592
+ l = tree.l
593
+ r = tree.r
594
+ simplified_const = l.val + r.r.val #plus(l.val, r.r.val)
595
+ tree.r = tree.r.l
596
+ tree.l.val = simplified_const
597
+ end
598
  end
599
+ else #tree.r.constant is true
600
+ if tree.l.degree == 2 && binops[tree.l.op] === sub
601
+ if tree.l.l.constant
602
+ #((const - var) - const) => (const - var)
603
+ l = tree.l
604
+ r = tree.r
605
+ simplified_const = l.l.val - r.val#sub(l.l.val, r.val)
606
+ tree.r = tree.l.r
607
+ tree.l = r
608
+ tree.l.val = simplified_const
609
+ elseif tree.l.r.constant
610
+ #((var - const) - const) => (var - const)
611
+ l = tree.l
612
+ r = tree.r
613
+ simplified_const = r.val + l.r.val #plus(r.val, l.r.val)
614
+ tree.l = tree.l.l
615
+ tree.r.val = simplified_const
616
  end
617
  end
618
  end