1 package org.simantics.scl.compiler.elaboration.chr.analysis;
\r
3 import java.util.ArrayList;
\r
5 import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
\r
6 import org.simantics.scl.compiler.elaboration.chr.CHRRule;
\r
7 import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;
\r
8 import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
\r
10 import gnu.trove.map.hash.THashMap;
\r
12 public class UsageAnalysis {
\r
13 public static void analyzeUsage(CHRRuleset ruleset) {
\r
14 THashMap<CHRConstraint,ArrayList<CHRRule>> headConstraintMap = createHeadConstraintMap(ruleset);
\r
15 calculateFirstPriorities(ruleset, headConstraintMap);
\r
16 calculateLastPriorities(ruleset, headConstraintMap);
\r
17 for(CHRRule rule : ruleset.rules)
\r
18 determinePassiveLiterals(rule);
\r
19 //printPriorities(ruleset);
\r
22 private static void calculateFirstPriorities(CHRRuleset ruleset,
\r
23 THashMap<CHRConstraint, ArrayList<CHRRule>> headConstraintMap) {
\r
24 for(CHRRule rule : ruleset.rules)
\r
25 rule.firstPriorityExecuted = Integer.MAX_VALUE;
\r
26 for(CHRConstraint constraint : ruleset.constraints) {
\r
27 constraint.firstPriorityAdded = Integer.MAX_VALUE;
\r
28 constraint.firstPriorityRemoved = Integer.MAX_VALUE;
\r
30 for(CHRRule rule : ruleset.rules)
\r
31 calculateFirstPriority(headConstraintMap, rule);
\r
34 private static void calculateFirstPriority(THashMap<CHRConstraint, ArrayList<CHRRule>> headConstraintMap, CHRRule rule) {
\r
35 int result = rule.priority;
\r
36 for(CHRLiteral literal : rule.head.literals)
\r
37 if(literal.relation instanceof CHRConstraint) {
\r
38 CHRConstraint constraint = (CHRConstraint)literal.relation;
\r
39 int constraintPriority = constraint.firstPriorityAdded;
\r
40 if(constraintPriority == Integer.MAX_VALUE)
\r
42 result = Math.max(result, constraint.firstPriorityAdded);
\r
44 rule.firstPriorityExecuted = result;
\r
45 for(CHRLiteral literal : rule.head.literals)
\r
46 if(literal.killAfterMatch && literal.relation instanceof CHRConstraint) {
\r
47 CHRConstraint constraint = (CHRConstraint)literal.relation;
\r
48 if(constraint.firstPriorityRemoved != Integer.MAX_VALUE)
\r
50 constraint.firstPriorityRemoved = result;
\r
52 for(CHRLiteral literal : rule.body.literals)
\r
53 if(literal.relation instanceof CHRConstraint) {
\r
54 CHRConstraint constraint = (CHRConstraint)literal.relation;
\r
55 if(constraint.firstPriorityAdded != Integer.MAX_VALUE)
\r
57 constraint.firstPriorityAdded = result;
\r
58 ArrayList<CHRRule> list = headConstraintMap.get(constraint);
\r
61 for(CHRRule lowerPriorityRule : list)
\r
62 if(lowerPriorityRule.priority < rule.priority)
\r
63 calculateFirstPriority(headConstraintMap, lowerPriorityRule);
\r
67 private static void calculateLastPriorities(CHRRuleset ruleset,
\r
68 THashMap<CHRConstraint, ArrayList<CHRRule>> headConstraintMap) {
\r
69 for(CHRRule rule : ruleset.rules)
\r
70 rule.lastPriorityExecuted = Integer.MIN_VALUE;
\r
71 for(CHRConstraint constraint : ruleset.constraints) {
\r
72 constraint.lastPriorityAdded = Integer.MIN_VALUE;
\r
73 constraint.lastPriorityRemoved = Integer.MIN_VALUE;
\r
75 for(int i=ruleset.rules.size()-1;i>=0;--i) {
\r
76 CHRRule rule = ruleset.rules.get(i);
\r
77 if(rule.lastPriorityExecuted == Integer.MIN_VALUE)
\r
78 calculateLastPriority(headConstraintMap, rule, rule.priority);
\r
82 private static void calculateLastPriority(THashMap<CHRConstraint, ArrayList<CHRRule>> headConstraintMap,
\r
83 CHRRule rule, int priority) {
\r
84 rule.lastPriorityExecuted = priority;
\r
85 for(CHRLiteral literal : rule.head.literals)
\r
86 if(literal.killAfterMatch && literal.relation instanceof CHRConstraint) {
\r
87 CHRConstraint constraint = (CHRConstraint)literal.relation;
\r
88 if(constraint.lastPriorityRemoved != Integer.MIN_VALUE)
\r
90 constraint.lastPriorityRemoved = priority;
\r
92 for(CHRLiteral literal : rule.body.literals)
\r
93 if(literal.relation instanceof CHRConstraint) {
\r
94 CHRConstraint constraint = (CHRConstraint)literal.relation;
\r
95 if(constraint.lastPriorityAdded != Integer.MIN_VALUE)
\r
97 constraint.lastPriorityAdded = priority;
\r
98 ArrayList<CHRRule> list = headConstraintMap.get(constraint);
\r
101 for(CHRRule lowerPriorityRule : list)
\r
102 if(lowerPriorityRule.lastPriorityExecuted == Integer.MIN_VALUE)
\r
103 calculateLastPriority(headConstraintMap, lowerPriorityRule, priority);
\r
107 private static THashMap<CHRConstraint, ArrayList<CHRRule>> createHeadConstraintMap(CHRRuleset ruleset) {
\r
108 THashMap<CHRConstraint, ArrayList<CHRRule>> map = new THashMap<CHRConstraint, ArrayList<CHRRule>>();
\r
109 for(CHRRule rule : ruleset.rules)
\r
110 for(CHRLiteral literal : rule.head.literals)
\r
111 if(literal.relation instanceof CHRConstraint) {
\r
112 ArrayList<CHRRule> list = map.get(literal.relation);
\r
114 list = new ArrayList<CHRRule>();
\r
115 map.put((CHRConstraint)literal.relation, list);
\r
118 else if(list.get(list.size()-1) != rule)
\r
124 private static void printPriorities(CHRRuleset ruleset) {
\r
125 System.out.println("-------------------------------");
\r
126 for(CHRConstraint constraint : ruleset.constraints) {
\r
127 System.out.print(" [" + constraint.firstPriorityAdded + ".." + constraint.lastPriorityAdded + "]");
\r
128 if(constraint.firstPriorityRemoved != Integer.MAX_VALUE)
\r
129 System.out.print("R[" + constraint.firstPriorityRemoved + ".." + constraint.lastPriorityRemoved + "]");
\r
130 System.out.print(" ");
\r
131 System.out.println(constraint);
\r
133 for(CHRRule rule : ruleset.rules) {
\r
134 System.out.print(rule.priority);
\r
135 System.out.print(" [" + rule.firstPriorityExecuted + ".." + rule.lastPriorityExecuted + "] ");
\r
136 System.out.println(rule);
\r
140 private static void determinePassiveLiterals(CHRRule rule) {
\r
141 for(CHRLiteral literal : rule.head.literals) {
\r
142 if(literal.passive)
\r
144 CHRConstraint constraint = (CHRConstraint)literal.relation;
\r
145 if(constraint.lastPriorityAdded < rule.priority)
\r
146 literal.passive = true;
\r