makeDeltaRules creates delta rules to check if newly added facts lead to new derivations.
(decls map[ast.PredicateSym]*ast.Decl, predToRules map[ast.PredicateSym][]ast.Clause)
| 363 | |
| 364 | // makeDeltaRules creates delta rules to check if newly added facts lead to new derivations. |
| 365 | func makeDeltaRules(decls map[ast.PredicateSym]*ast.Decl, predToRules map[ast.PredicateSym][]ast.Clause) map[ast.PredicateSym][]ast.Clause { |
| 366 | predToDeltaRules := make(map[ast.PredicateSym][]ast.Clause) |
| 367 | for _, decl := range decls { |
| 368 | pred := decl.DeclaredAtom.Predicate |
| 369 | rules := predToRules[pred] |
| 370 | for _, clause := range rules { |
| 371 | if clause.Transform != nil && !clause.Transform.IsLetTransform() { |
| 372 | // Rules with do-transforms are only applied at the very end. |
| 373 | continue |
| 374 | } |
| 375 | var deltaRules []ast.Clause |
| 376 | for i, subgoal := range clause.Premises { |
| 377 | // Create delta rule for each subgoal matching positive atoms from last round. |
| 378 | var pred ast.PredicateSym |
| 379 | switch p := subgoal.(type) { |
| 380 | case ast.Atom: |
| 381 | pred = p.Predicate |
| 382 | case ast.TemporalLiteral: |
| 383 | if atom, ok := p.Literal.(ast.Atom); ok { |
| 384 | pred = atom.Predicate |
| 385 | } |
| 386 | } |
| 387 | |
| 388 | if pred.Symbol == "" || pred.IsBuiltin() { |
| 389 | continue |
| 390 | } |
| 391 | if _, ok := decls[pred]; ok { |
| 392 | deltaRule := makeSingleDeltaRule(clause, i) |
| 393 | deltaRules = append(deltaRules, deltaRule) |
| 394 | } |
| 395 | } |
| 396 | predToDeltaRules[pred] = append(predToDeltaRules[pred], deltaRules...) |
| 397 | } |
| 398 | } |
| 399 | return predToDeltaRules |
| 400 | } |
| 401 | |
| 402 | func (e *engine) hasMergePredicate(pred ast.PredicateSym) (ast.FunDep, ast.PredicateSym, bool) { |
| 403 | decl := e.predToDecl[pred] |