public ExpressionSimplifier(SegmentMap segmentMap, EvaluationContext ctx, DecompilerEventListener listener)
        {
            this.segmentMap = segmentMap ?? throw new ArgumentNullException(nameof(SegmentMap));
            this.ctx        = ctx;
            this.cmp        = new ExpressionValueComparer();

            this.add2ids                 = new AddTwoIdsRule(ctx);
            this.addEcc                  = new Add_e_c_cRule(ctx);
            this.addMici                 = new Add_mul_id_c_id_Rule(ctx);
            this.idConst                 = new IdConstant(ctx, new Unifier(), listener);
            this.idCopyPropagation       = new IdCopyPropagationRule(ctx);
            this.idBinIdc                = new IdBinIdc_Rule(ctx);
            this.sliceConst              = new SliceConstant_Rule();
            this.sliceMem                = new SliceMem_Rule();
            this.sliceSegPtr             = new SliceSegmentedPointer_Rule(ctx);
            this.negSub                  = new NegSub_Rule();
            this.constConstBin           = new ConstConstBin_Rule();
            this.shAdd                   = new Shl_add_Rule(ctx);
            this.shMul                   = new Shl_mul_e_Rule(ctx);
            this.shiftShift              = new ShiftShift_c_c_Rule(ctx);
            this.mpsRule                 = new Mps_Constant_Rule(ctx);
            this.sliceShift              = new SliceShift(ctx);
            this.binopWithSelf           = new BinOpWithSelf_Rule();
            this.constDiv                = new ConstDivisionImplementedByMultiplication(ctx);
            this.idProcConstRule         = new IdProcConstRule(ctx);
            this.castCastRule            = new CastCastRule(ctx);
            this.distributedCast         = new DistributedCastRule();
            this.distributedSlice        = new DistributedSliceRule();
            this.mkSeqFromSlicesRule     = new MkSeqFromSlices_Rule(ctx);
            this.constOnLeft             = new ComparisonConstOnLeft();
            this.sliceSeq                = new SliceSequence(ctx);
            this.logicalNotFollowedByNeg = new LogicalNotFollowedByNegRule();
            this.logicalNotFromBorrow    = new LogicalNotFromArithmeticSequenceRule();
            this.unaryNegEqZero          = new UnaryNegEqZeroRule();
        }