コード例 #1
0
ファイル: dlprim.go プロジェクト: kevinawalsh/datalog
func (eq *eqPrim) Search(target *datalog.Literal, discovered func(c *datalog.Clause)) {
	a := target.Arg[0]
	b := target.Arg[1]
	if a.Variable() && b.Constant() {
		discovered(datalog.NewClause(datalog.NewLiteral(eq, b, b)))
	} else if a.Constant() && b.Variable() {
		discovered(datalog.NewClause(datalog.NewLiteral(eq, a, a)))
	} else if a.Constant() && b.Constant() && a == b {
		discovered(datalog.NewClause(target))
	}
}
コード例 #2
0
// Search implements the subprinPrim custom datalog primitive by parsing
// constant arguments of subprin/3 as principals and reporting any clauses it
// discovers.
func (sp *subprinPrim) Search(target *datalog.Literal, discovered func(c *datalog.Clause)) {
	p := target.Arg[0]
	o := target.Arg[1]
	e := target.Arg[2]
	if p.Constant() && o.Variable() && e.Variable() {
		prin, err := parseCompositePrin(p)
		if err != nil {
			return
		}
		extIndex := len(prin.Ext) - 1
		trimmedPrin := auth.Prin{
			Type: prin.Type,
			Key:  prin.Key,
			Ext:  prin.Ext[:extIndex],
		}
		extPrin := auth.PrinTail{
			Ext: []auth.PrinExt{prin.Ext[extIndex]},
		}

		parentIdent := dlengine.NewIdent(fmt.Sprintf("%q", trimmedPrin.String()))
		extIdent := dlengine.NewIdent(fmt.Sprintf("%q", extPrin.String()))
		discovered(datalog.NewClause(datalog.NewLiteral(sp, p, parentIdent, extIdent)))
	} else if p.Variable() && o.Constant() && e.Constant() {
		oprin, eprin, err := parseRootExtPrins(o, e)
		if err != nil {
			return
		}
		oprin.Ext = append(oprin.Ext, eprin.Ext...)
		oeIdent := dlengine.NewIdent(fmt.Sprintf("%q", oprin.String()))
		if len(oprin.Ext)+1 <= sp.max {
			discovered(datalog.NewClause(datalog.NewLiteral(sp, oeIdent, o, e)))
		}
	} else if p.Constant() && o.Constant() && e.Constant() {
		// Check that the constraint holds and report it as discovered.
		prin, err := parseCompositePrin(p)
		if err != nil {
			return
		}
		oprin, eprin, err := parseRootExtPrins(o, e)
		if err != nil {
			return
		}

		// Extend the root principal with the extension from the ext principal
		// and check identity. Make sure the constructed principal does
		// not exceed the given maximum principal length.
		oprin.Ext = append(oprin.Ext, eprin.Ext...)
		if prin.Identical(oprin) {
			discovered(datalog.NewClause(datalog.NewLiteral(sp, p, o, e)))
		}
	}
}
コード例 #3
0
ファイル: dlengine.go プロジェクト: kevinawalsh/datalog
func (e *Engine) recoverLiteral(literal *literalNode) *datalog.Literal {
	name := literal.predsym
	arity := len(literal.nodeList)
	id := name + "/" + strconv.Itoa(arity)
	p, ok := e.Pred[id]
	if !ok {
		p = NewPred(name, arity)
		e.Pred[id] = p
	}
	arg := make([]datalog.Term, arity)
	for i, n := range literal.nodeList {
		leaf := n.(*leafNode)
		t, ok := e.Term[leaf.val]
		if !ok {
			switch n.Type() {
			case nodeIdentifier:
				t = NewIdent(leaf.val)
			case nodeString:
				t = NewQuoted(leaf.val)
			case nodeVariable:
				t = NewVar(leaf.val)
			default:
				panic("not reached")
			}
			e.Term[leaf.val] = t
		}
		arg[i] = t
	}
	return datalog.NewLiteral(p, arg...)
}