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)) } }
// 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))) } } }
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...) }