Rewrite transforms each clause of a given layer (stratum) of a program to another one where transforms only appear on clauses with a single atom that defines all variables.
(stratum analysis.Program)
| 34 | // Rewrite transforms each clause of a given layer (stratum) of a program to another one where |
| 35 | // transforms only appear on clauses with a single atom that defines all variables. |
| 36 | func Rewrite(stratum analysis.Program) analysis.Program { |
| 37 | gen := freshNameGenerator() |
| 38 | |
| 39 | var newRules []ast.Clause |
| 40 | for _, clause := range stratum.Rules { |
| 41 | if (clause.Transform == nil) || clause.Transform.IsLetTransform() || isSingleAtomPremise(clause.Premises) { |
| 42 | newRules = append(newRules, clause) |
| 43 | continue |
| 44 | } |
| 45 | |
| 46 | // Make a new predicate that captures all variables. |
| 47 | p := clause.Head.Predicate |
| 48 | |
| 49 | vars := make(map[ast.Variable]bool) |
| 50 | for _, premise := range clause.Premises { |
| 51 | getVars(premise, vars) |
| 52 | } |
| 53 | // Wildcard variables _ do not correspond to any column in the result relation. |
| 54 | delete(vars, ast.Variable{"_"}) |
| 55 | |
| 56 | internalPred := gen.freshPredicateName(p, len(vars)) |
| 57 | |
| 58 | newHead := makeHead(internalPred, vars) |
| 59 | newRules = append(newRules, ast.Clause{newHead, nil, clause.Premises, nil}) |
| 60 | newRules = append(newRules, ast.Clause{clause.Head, clause.HeadTime, []ast.Term{newHead}, clause.Transform}) |
| 61 | } |
| 62 | return analysis.Program{stratum.EdbPredicates, stratum.IdbPredicates, newRules} |
| 63 | } |
| 64 | |
| 65 | type nameGen struct { |
| 66 | n int |