Beispiel #1
0
func TestSimplifyTree(t *testing.T) {
	left := ast.NewTreeNode(ast.NewStringName("A"),
		ast.NewTreeNode(ast.NewStringName("B"), ast.NewContains(
			ast.NewTreeNode(ast.NewStringName("C"), ast.NewZAny()),
		)),
	)
	right := ast.NewTreeNode(ast.NewStringName("A"),
		ast.NewTreeNode(ast.NewStringName("B"), ast.NewContains(
			ast.NewTreeNode(ast.NewStringName("D"), ast.NewZAny()),
		)),
	)
	input := ast.NewAnd(left, right)
	expected := ast.NewTreeNode(ast.NewStringName("A"),
		ast.NewTreeNode(ast.NewStringName("B"), ast.NewAnd(
			ast.NewContains(
				ast.NewTreeNode(ast.NewStringName("C"), ast.NewZAny()),
			),
			ast.NewContains(
				ast.NewTreeNode(ast.NewStringName("D"), 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)
	}
}
Beispiel #2
0
func TestSimplify1(t *testing.T) {
	c := ast.NewConcat(ast.NewNot(ast.NewZAny()), ast.NewZAny())
	s := NewSimplifier(c.Grammar()).Simplify(c)
	if !s.Equal(ast.NewNot(ast.NewZAny())) {
		t.Fatalf("Expected EmptySet, but got %s", s)
	}
}
Beispiel #3
0
func TestSimplifyContainsFalseTreeNode(t *testing.T) {
	input := ast.NewContains(ast.NewTreeNode(ast.NewAnyNameExcept(ast.NewAnyName()), ast.NewZAny()))
	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)
	}
}
Beispiel #4
0
func TestSimplifyTreeNodeWithNotZanyChild(t *testing.T) {
	input := ast.NewTreeNode(ast.NewAnyName(), ast.NewNot(ast.NewZAny()))
	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)
	}
}
Beispiel #5
0
func TestKeyAnyName(t *testing.T) {
	p := ast.NewOr(
		ast.NewTreeNode(ast.NewNameChoice(ast.NewAnyName(), ast.NewStringName("C")), ast.NewZAny()),
		ast.NewTreeNode(ast.NewStringName("B"), ast.NewZAny()),
	)
	g := p.Grammar()
	gkey, err := FieldNamesToNumbers("debug", "Debug", debug.DebugDescription(), g)
	if err == nil {
		t.Fatalf("Expected: Any Field Not Supported: Name: _, but got %v", gkey)
	}
}
Beispiel #6
0
func TestNotUnreachableArray(t *testing.T) {
	p := ast.NewTreeNode(ast.NewAnyNameExcept(ast.NewStringName("NotC")), ast.NewTreeNode(ast.NewStringName("F"),
		ast.NewConcat(ast.NewZAny(), ast.NewTreeNode(ast.NewAnyName(),
			ast.NewZAny(),
		))))
	g := p.Grammar()
	gkey, err := FieldNamesToNumbers("debug", "Debug", debug.DebugDescription(), g)
	if err == nil {
		t.Fatalf("Expected: AnyNameExcept Not Supported Error: Name: !(NotC), but got %v", gkey)
	}
}
Beispiel #7
0
func TestAnyIndex(t *testing.T) {
	p := ast.NewTreeNode(ast.NewStringName("KeyValue"), ast.NewTreeNode(ast.NewAnyName(), ast.NewConcat(
		ast.NewTreeNode(ast.NewStringName("Key"), ast.NewZAny()),
		ast.NewTreeNode(ast.NewStringName("Value"), ast.NewZAny()),
	)))
	gkey, err := FieldNamesToNumbers("protonum", "ProtoNum", ProtonumDescription(), p.Grammar())
	if err != nil {
		t.Fatal(err)
	}
	t.Logf("%v", gkey)
	check(t, gkey)
}
Beispiel #8
0
func derivReturn(refs ast.RefLookup, p *ast.Pattern, patterns []*ast.Pattern) (*ast.Pattern, []*ast.Pattern) {
	typ := p.GetValue()
	switch v := typ.(type) {
	case *ast.Empty:
		return ast.NewNot(ast.NewZAny()), patterns
	case *ast.ZAny:
		return ast.NewZAny(), patterns
	case *ast.TreeNode:
		if Nullable(refs, patterns[0]) {
			return ast.NewEmpty(), patterns[1:]
		}
		return ast.NewNot(ast.NewZAny()), patterns[1:]
	case *ast.LeafNode:
		if Nullable(refs, patterns[0]) {
			return ast.NewEmpty(), patterns[1:]
		}
		return ast.NewNot(ast.NewZAny()), patterns[1:]
	case *ast.Concat:
		l, leftRest := derivReturn(refs, v.GetLeftPattern(), patterns)
		leftConcat := ast.NewConcat(l, v.GetRightPattern())
		if !Nullable(refs, v.GetLeftPattern()) {
			return leftConcat, leftRest
		}
		r, rightRest := derivReturn(refs, v.GetRightPattern(), leftRest)
		return ast.NewOr(leftConcat, r), rightRest
	case *ast.Or:
		l, leftRest := derivReturn(refs, v.GetLeftPattern(), patterns)
		r, rightRest := derivReturn(refs, v.GetRightPattern(), leftRest)
		return ast.NewOr(l, r), rightRest
	case *ast.And:
		l, leftRest := derivReturn(refs, v.GetLeftPattern(), patterns)
		r, rightRest := derivReturn(refs, v.GetRightPattern(), leftRest)
		return ast.NewAnd(l, r), rightRest
	case *ast.Interleave:
		l, leftRest := derivReturn(refs, v.GetLeftPattern(), patterns)
		r, rightRest := derivReturn(refs, v.GetRightPattern(), leftRest)
		return ast.NewOr(ast.NewInterleave(l, v.GetRightPattern()), ast.NewInterleave(r, v.GetLeftPattern())), rightRest
	case *ast.ZeroOrMore:
		c, rest := derivReturn(refs, v.GetPattern(), patterns)
		return ast.NewConcat(c, p), rest
	case *ast.Reference:
		return derivReturn(refs, refs[v.GetName()], patterns)
	case *ast.Not:
		c, rest := derivReturn(refs, v.GetPattern(), patterns)
		return ast.NewNot(c), rest
	case *ast.Contains:
		return derivReturn(refs, ast.NewConcat(ast.NewZAny(), ast.NewConcat(v.GetPattern(), ast.NewZAny())), patterns)
	case *ast.Optional:
		return derivReturn(refs, ast.NewOr(v.GetPattern(), ast.NewEmpty()), patterns)
	}
	panic(fmt.Sprintf("unknown pattern typ %T", typ))
}
Beispiel #9
0
func TestTopsyTurvy(t *testing.T) {
	p := ast.NewTreeNode(ast.NewAnyName(), ast.NewTreeNode(ast.NewStringName("A"), ast.NewZAny()))
	gkey, err := FieldNamesToNumbers("protonum", "TopsyTurvy", ProtonumDescription(), p.Grammar())
	if err == nil {
		t.Fatalf("Expected: Any Field Not Supported: Name: _, but got %v", gkey)
	}
}
Beispiel #10
0
func simplifyContains(p *ast.Pattern) *ast.Pattern {
	if isEmpty(p) || isZany(p) {
		return ast.NewZAny()
	}
	if isNotZany(p) {
		return p
	}
	return ast.NewContains(p)
}
Beispiel #11
0
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)
	}
}
Beispiel #12
0
func TestKeyOr(t *testing.T) {
	p := ast.NewOr(
		ast.NewTreeNode(ast.NewStringName("A"), ast.NewZAny()),
		ast.NewTreeNode(ast.NewStringName("B"), ast.NewZAny()),
	)
	g := p.Grammar()
	gkey, err := FieldNamesToNumbers("debug", "Debug", debug.DebugDescription(), g)
	if err != nil {
		t.Fatal(err)
	}
	t.Logf("%v", gkey)
	check(t, gkey)
	if gkey.GetTopPattern().GetOr().GetLeftPattern().GetTreeNode().GetName().GetName().GetUintValue() != 1 {
		t.Fatalf("expected field 1, but got %v", gkey)
	}
	if gkey.GetTopPattern().GetOr().GetRightPattern().GetTreeNode().GetName().GetName().GetUintValue() != 2 {
		t.Fatalf("expected field 2, but got %v", gkey)
	}
}
Beispiel #13
0
func newList(nameOrPattern *NameOrPattern) *ast.Pattern {
	regexStr, nullable, err := listToRegex(nameOrPattern)
	if err != nil {
		return ast.NewNot(ast.NewZAny())
	}
	val := combinator.Value(&list{nil, funcs.StringVar(), funcs.StringConst("^" + regexStr + "$")})
	if !nullable {
		return val
	}
	return ast.NewOr(val, ast.NewEmpty())
}
Beispiel #14
0
func TestKeyAnyArrayIndex(t *testing.T) {
	p := ast.NewConcat(
		ast.NewZAny(),
		ast.NewTreeNode(ast.NewStringName("E"),
			ast.NewTreeNode(ast.NewAnyName(),
				ast.NewConcat(
					ast.NewTreeNode(ast.NewStringName("A"), ast.NewZAny()),
					ast.NewTreeNode(ast.NewStringName("B"), ast.NewZAny()),
				),
			),
		),
		ast.NewZAny(),
	)
	g := p.Grammar()
	gkey, err := FieldNamesToNumbers("debug", "Debug", debug.DebugDescription(), g)
	if err != nil {
		t.Fatal(err)
	}
	t.Logf("%v", gkey)
	check(t, gkey)
}
Beispiel #15
0
func TestRepeatedMessageWithNoFieldsOfTypeMessage(t *testing.T) {
	p := ast.NewConcat(
		ast.NewZAny(),
		ast.NewTreeNode(ast.NewStringName("KeyValue"),
			ast.NewTreeNode(ast.NewAnyName(),
				ast.NewConcat(
					ast.NewTreeNode(ast.NewStringName("Key"), ast.NewZAny()),
					ast.NewTreeNode(ast.NewStringName("Value"), ast.NewZAny()),
				),
			),
		),
		ast.NewZAny(),
	)
	g := p.Grammar()
	gkey, err := FieldNamesToNumbers("protonum", "ProtoNum", ProtonumDescription(), g)
	if err != nil {
		t.Fatal(err)
	}
	t.Logf("%v", gkey)
	check(t, gkey)
}
Beispiel #16
0
func derivCall(refs map[string]*ast.Pattern, getFunc func(*ast.Expr) funcs.Bool, p *ast.Pattern) []*ifExpr {
	typ := p.GetValue()
	switch v := typ.(type) {
	case *ast.Empty:
		return []*ifExpr{}
	case *ast.ZAny:
		return []*ifExpr{}
	case *ast.TreeNode:
		b := nameexpr.NameToFunc(v.GetName())
		return []*ifExpr{{b, v.GetPattern(), ast.NewNot(ast.NewZAny())}}
	case *ast.LeafNode:
		b := getFunc(v.GetExpr())
		return []*ifExpr{{b, ast.NewEmpty(), ast.NewNot(ast.NewZAny())}}
	case *ast.Concat:
		l := derivCall(refs, getFunc, v.GetLeftPattern())
		if !interp.Nullable(refs, v.GetLeftPattern()) {
			return l
		}
		r := derivCall(refs, getFunc, v.GetRightPattern())
		return append(l, r...)
	case *ast.Or:
		return derivCall2(refs, getFunc, v.GetLeftPattern(), v.GetRightPattern())
	case *ast.And:
		return derivCall2(refs, getFunc, v.GetLeftPattern(), v.GetRightPattern())
	case *ast.Interleave:
		return derivCall2(refs, getFunc, v.GetLeftPattern(), v.GetRightPattern())
	case *ast.ZeroOrMore:
		return derivCall(refs, getFunc, v.GetPattern())
	case *ast.Reference:
		return derivCall(refs, getFunc, refs[v.GetName()])
	case *ast.Not:
		return derivCall(refs, getFunc, v.GetPattern())
	case *ast.Contains:
		return derivCall(refs, getFunc, ast.NewConcat(ast.NewZAny(), ast.NewConcat(v.GetPattern(), ast.NewZAny())))
	case *ast.Optional:
		return derivCall(refs, getFunc, ast.NewOr(v.GetPattern(), ast.NewEmpty()))
	}
	panic(fmt.Sprintf("unknown pattern typ %T", typ))
}
Beispiel #17
0
func TestKeyRecursive(t *testing.T) {
	p := ast.NewOr(
		ast.NewTreeNode(ast.NewStringName("C"), ast.NewReference("main")),
		ast.NewTreeNode(ast.NewStringName("A"), ast.NewZAny()),
	)
	g := p.Grammar()
	gkey, err := FieldNamesToNumbers("debug", "Debug", debug.DebugDescription(), g)
	if err != nil {
		t.Fatal(err)
	}
	t.Logf("%v", gkey)
	check(t, gkey)
}
Beispiel #18
0
func TestKeyLeftRecursive(t *testing.T) {
	p := ast.NewOr(
		ast.NewReference("a"),
		ast.NewTreeNode(ast.NewStringName("C"), ast.NewReference("main")),
		ast.NewTreeNode(ast.NewStringName("A"), ast.NewZAny()),
	)
	g := p.Grammar().AddRef("a", ast.NewReference("main"))
	gkey, err := FieldNamesToNumbers("debug", "Debug", debug.DebugDescription(), g)
	if err != nil {
		t.Fatal(err)
	}
	t.Logf("%v", gkey)
	if gkey.GetTopPattern().GetOr().GetRightPattern().GetOr().GetLeftPattern().GetTreeNode().GetName().GetName().GetUintValue() != 3 {
		t.Fatalf("expected field 3, but got %v", gkey)
	}
	check(t, gkey)
}
Beispiel #19
0
func simplifyOr(refs ast.RefLookup, p1, p2 *ast.Pattern, record bool) *ast.Pattern {
	if isNotZany(p1) {
		return p2
	}
	if isNotZany(p2) {
		return p1
	}
	if isZany(p1) || isZany(p2) {
		return ast.NewZAny()
	}
	if isEmpty(p1) && Nullable(refs, p2) {
		return p2
	}
	if isEmpty(p2) && Nullable(refs, p1) {
		return p1
	}
	if p1.GetLeafNode() != nil && p2.GetLeafNode() != nil {
		expr1, err1 := compose.ConvertBuiltInIntoFunction(p1.GetLeafNode().GetExpr())
		expr2, err2 := compose.ConvertBuiltInIntoFunction(p2.GetLeafNode().GetExpr())
		if err1 == nil && err2 == nil {
			return ast.NewLeafNode(ast.NewFunction("or", expr1, expr2))
		}
	}
	left := getOrs(p1)
	right := getOrs(p2)
	list := append(left, right...)
	list = ast.Set(list)
	list = simplifyChildren(list, func(left, right *ast.Pattern) *ast.Pattern {
		return simplifyOr(refs, left, right, record)
	}, record)
	ast.Sort(list)
	var p *ast.Pattern = list[0]
	for i := range list {
		if i == 0 {
			continue
		}
		p = ast.NewOr(p, list[i])
	}
	return p
}
Beispiel #20
0
func (this *simplifier) OptimizeForRecord() Simplifier {
	this.record = true
	return this
}

func checkRef(refs ast.RefLookup, p *ast.Pattern) *ast.Pattern {
	for name, rpat := range refs {
		if rpat.Equal(p) {
			return ast.NewReference(name)
		}
	}
	return p
}

var emptyset = ast.NewNot(ast.NewZAny())

func (this *simplifier) simplify(p *ast.Pattern, top bool) *ast.Pattern {
	cRef := func(cp *ast.Pattern) *ast.Pattern {
		if top {
			return cp
		}
		return checkRef(this.refs, cp)
	}
	cachesimp := func(sp *ast.Pattern) *ast.Pattern {
		if _, ok := this.cache[sp]; ok {
			return sp
		}
		s := this.simplify(sp, false)
		this.cache[s] = struct{}{}
		return s
Beispiel #21
0
func TestUnreachable(t *testing.T) {
	p := ast.NewTreeNode(ast.NewStringName("NotC"), ast.NewTreeNode(ast.NewStringName("C"), ast.NewTreeNode(ast.NewStringName("A"), ast.NewZAny())))
	g := p.Grammar()
	gkey, err := FieldNamesToNumbers("debug", "Debug", debug.DebugDescription(), g)
	if err == nil {
		t.Fatalf("Expected: Unknown Field Error: Name: NotC, Msg: Debug, but got %v", gkey)
	}
}
Beispiel #22
0
func derivCall(refs ast.RefLookup, p *ast.Pattern, label parser.Value) ([]*ast.Pattern, error) {
	typ := p.GetValue()
	switch v := typ.(type) {
	case *ast.Empty:
		return []*ast.Pattern{}, nil
	case *ast.ZAny:
		return []*ast.Pattern{}, nil
	case *ast.TreeNode:
		b := nameexpr.NameToFunc(v.GetName())
		f, err := compose.NewBoolFunc(b)
		if err != nil {
			return nil, err
		}
		eval, err := f.Eval(label)
		if err != nil {
			return nil, err
		}
		if eval {
			return []*ast.Pattern{v.GetPattern()}, nil
		}
		return []*ast.Pattern{ast.NewNot(ast.NewZAny())}, nil
	case *ast.LeafNode:
		b, err := compose.NewBool(v.GetExpr())
		if err != nil {
			return nil, err
		}
		f, err := compose.NewBoolFunc(b)
		if err != nil {
			return nil, err
		}
		eval, err := f.Eval(label)
		if err != nil {
			return nil, err
		}
		if eval {
			return []*ast.Pattern{ast.NewEmpty()}, nil
		}
		return []*ast.Pattern{ast.NewNot(ast.NewZAny())}, nil
	case *ast.Concat:
		l, err := derivCall(refs, v.GetLeftPattern(), label)
		if err != nil {
			return nil, err
		}
		if !Nullable(refs, v.GetLeftPattern()) {
			return l, nil
		}
		r, err := derivCall(refs, v.GetRightPattern(), label)
		if err != nil {
			return nil, err
		}
		return append(l, r...), nil
	case *ast.Or:
		return derivCall2(refs, v.GetLeftPattern(), v.GetRightPattern(), label)
	case *ast.And:
		return derivCall2(refs, v.GetLeftPattern(), v.GetRightPattern(), label)
	case *ast.Interleave:
		return derivCall2(refs, v.GetLeftPattern(), v.GetRightPattern(), label)
	case *ast.ZeroOrMore:
		return derivCall(refs, v.GetPattern(), label)
	case *ast.Reference:
		return derivCall(refs, refs[v.GetName()], label)
	case *ast.Not:
		return derivCall(refs, v.GetPattern(), label)
	case *ast.Contains:
		return derivCall(refs, ast.NewConcat(ast.NewZAny(), ast.NewConcat(v.GetPattern(), ast.NewZAny())), label)
	case *ast.Optional:
		return derivCall(refs, ast.NewOr(v.GetPattern(), ast.NewEmpty()), label)
	}
	panic(fmt.Sprintf("unknown pattern typ %T", typ))
}
Beispiel #23
0
func TestRecursiveKnotElbow(t *testing.T) {
	p := ast.NewOr(ast.NewTreeNode(ast.NewAnyName(), ast.NewReference("main")), ast.NewTreeNode(ast.NewStringName("Elbow"), ast.NewZAny()))
	gkey, err := FieldNamesToNumbers("protonum", "Knot", ProtonumDescription(), p.Grammar())
	if err == nil {
		t.Fatalf("Expected: Any Field Not Supported: Name: _, but got %v", gkey)
	}
}
Beispiel #24
0
func TestSimplify2(t *testing.T) {
	s := NewSimplifier(andNameTelephonePerson.Grammar()).Simplify(andNameTelephonePerson["main"])
	if s.Equal(ast.NewNot(ast.NewZAny())) {
		t.Fatalf("Did not expected EmptySet")
	}
}
Beispiel #25
0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.

package mem

import (
	"github.com/katydid/katydid/relapse/ast"
)

var (
	zipIgnoreSet = []*ast.Pattern{
		ast.NewZAny(),
		ast.NewNot(ast.NewZAny()),
	}
	zignoreb = []bool{
		true,
		false,
	}
)

func zip(patterns []*ast.Pattern) ([]*ast.Pattern, []int) {
	set := ast.Set(patterns)
	ast.Sort(set)

	if index := ast.Index(set, zipIgnoreSet[0]); index != -1 {
		set = ast.Remove(set, index)
	}