func (this *ifExprs) addIfExpr(cond funcs.Bool, then, els *ast.Pattern) { // efficienctly append the then and else return to two copies of the current returns. if this.ret != nil { this.cond = cond thenterms := make([]*ast.Pattern, len(this.ret)+1) copy(thenterms, this.ret) thenterms[len(thenterms)-1] = then this.then = &ifExprs{ret: thenterms} this.els = &ifExprs{ret: append(this.ret, els)} this.ret = nil return } // remove duplicate condition if funcs.Equal(this.cond, cond) { this.then.addReturn(then) this.els.addReturn(els) return } // remove impossible (always false) then condition if funcs.IsFalse(funcs.Simplify(funcs.And(this.cond, cond))) { this.then.addReturn(els) this.els.addIfExpr(cond, then, els) return } // remove impossible (always false) else condition if funcs.IsFalse(funcs.Simplify(funcs.And(this.cond, funcs.Not(cond)))) { this.then.addIfExpr(cond, then, els) this.els.addReturn(then) return } this.then.addIfExpr(cond, then, els) this.els.addIfExpr(cond, then, els) return }
func TestSimplifyFalseLeaf(t *testing.T) { input := combinator.Value(funcs.And(funcs.StringEq(funcs.StringVar(), funcs.StringConst("a")), funcs.StringEq(funcs.StringVar(), funcs.StringConst("b")))) expected := ast.NewNot(ast.NewZAny()) output := NewSimplifier(input.Grammar()).Simplify(input) t.Logf("%v", output) if !expected.Equal(output) { t.Fatalf("expected %v, but got %v", expected, output) } }
func TestSimplifyRecordLeaf2(t *testing.T) { input := ast.NewAnd( ast.NewContains(ast.NewTreeNode(ast.NewStringName("A"), ast.NewContains(ast.NewTreeNode(ast.NewStringName("B"), combinator.Value(funcs.Contains(funcs.StringVar(), funcs.StringConst("a"))))))), ast.NewContains(ast.NewTreeNode(ast.NewStringName("A"), ast.NewContains(ast.NewTreeNode(ast.NewStringName("B"), combinator.Value(funcs.Contains(funcs.StringVar(), funcs.StringConst("b"))))))), ) t.Logf("input: %v", input) expected := ast.NewContains(ast.NewTreeNode(ast.NewStringName("A"), ast.NewContains(ast.NewTreeNode(ast.NewStringName("B"), combinator.Value(funcs.And( funcs.Contains(funcs.StringVar(), funcs.StringConst("a")), funcs.Contains(funcs.StringVar(), funcs.StringConst("b")), )))))) output := NewSimplifier(input.Grammar()).OptimizeForRecord().Simplify(input) expected.Format() output.Format() t.Logf("%v", output) if !expected.Equal(output) { t.Fatalf("expected %v, but got %v", expected, output) } }