X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Felaboration%2Fchr%2Fanalysis%2FUsageAnalysis.java;h=a738c1f42126ebc7d0f01788f2e48ce1129021f3;hp=3e13e0f3f8feb32c77dda1fbf9eddc0690e2763b;hb=1ec0193a5a5b8f368b03adb24acd762838ddf8ea;hpb=1b4d8b692f40d946deb5db8280eb4ca5b36a75a7 diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/analysis/UsageAnalysis.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/analysis/UsageAnalysis.java index 3e13e0f3f..a738c1f42 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/analysis/UsageAnalysis.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/analysis/UsageAnalysis.java @@ -1,149 +1,150 @@ -package org.simantics.scl.compiler.elaboration.chr.analysis; - -import java.util.ArrayList; - -import org.simantics.scl.compiler.elaboration.chr.CHRLiteral; -import org.simantics.scl.compiler.elaboration.chr.CHRRule; -import org.simantics.scl.compiler.elaboration.chr.CHRRuleset; -import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint; - -import gnu.trove.map.hash.THashMap; - -public class UsageAnalysis { - public static void analyzeUsage(CHRRuleset ruleset) { - THashMap> headConstraintMap = createHeadConstraintMap(ruleset); - calculateFirstPriorities(ruleset, headConstraintMap); - calculateLastPriorities(ruleset, headConstraintMap); - for(CHRRule rule : ruleset.rules) - determinePassiveLiterals(rule); - //printPriorities(ruleset); - } - - private static void calculateFirstPriorities(CHRRuleset ruleset, - THashMap> headConstraintMap) { - for(CHRRule rule : ruleset.rules) - rule.firstPriorityExecuted = Integer.MAX_VALUE; - for(CHRConstraint constraint : ruleset.constraints) { - constraint.firstPriorityAdded = Integer.MAX_VALUE; - constraint.firstPriorityRemoved = Integer.MAX_VALUE; - } - for(CHRRule rule : ruleset.rules) - calculateFirstPriority(headConstraintMap, rule); - } - - private static void calculateFirstPriority(THashMap> headConstraintMap, CHRRule rule) { - int result = rule.priority; - for(CHRLiteral literal : rule.head.literals) - if(literal.relation instanceof CHRConstraint) { - CHRConstraint constraint = (CHRConstraint)literal.relation; - int constraintPriority = constraint.firstPriorityAdded; - if(constraintPriority == Integer.MAX_VALUE) - return; - result = Math.max(result, constraint.firstPriorityAdded); - } - rule.firstPriorityExecuted = result; - for(CHRLiteral literal : rule.head.literals) - if(literal.killAfterMatch && literal.relation instanceof CHRConstraint) { - CHRConstraint constraint = (CHRConstraint)literal.relation; - if(constraint.firstPriorityRemoved != Integer.MAX_VALUE) - continue; - constraint.firstPriorityRemoved = result; - } - for(CHRLiteral literal : rule.body.literals) - if(literal.relation instanceof CHRConstraint) { - CHRConstraint constraint = (CHRConstraint)literal.relation; - if(constraint.firstPriorityAdded != Integer.MAX_VALUE) - continue; - constraint.firstPriorityAdded = result; - ArrayList list = headConstraintMap.get(constraint); - if(list == null) - continue; - for(CHRRule lowerPriorityRule : list) - if(lowerPriorityRule.priority < rule.priority) - calculateFirstPriority(headConstraintMap, lowerPriorityRule); - } - } - - private static void calculateLastPriorities(CHRRuleset ruleset, - THashMap> headConstraintMap) { - for(CHRRule rule : ruleset.rules) - rule.lastPriorityExecuted = Integer.MIN_VALUE; - for(CHRConstraint constraint : ruleset.constraints) { - constraint.lastPriorityAdded = Integer.MIN_VALUE; - constraint.lastPriorityRemoved = Integer.MIN_VALUE; - } - for(int i=ruleset.rules.size()-1;i>=0;--i) { - CHRRule rule = ruleset.rules.get(i); - if(rule.lastPriorityExecuted == Integer.MIN_VALUE) - calculateLastPriority(headConstraintMap, rule, rule.priority); - } - } - - private static void calculateLastPriority(THashMap> headConstraintMap, - CHRRule rule, int priority) { - rule.lastPriorityExecuted = priority; - for(CHRLiteral literal : rule.head.literals) - if(literal.killAfterMatch && literal.relation instanceof CHRConstraint) { - CHRConstraint constraint = (CHRConstraint)literal.relation; - if(constraint.lastPriorityRemoved != Integer.MIN_VALUE) - continue; - constraint.lastPriorityRemoved = priority; - } - for(CHRLiteral literal : rule.body.literals) - if(literal.relation instanceof CHRConstraint) { - CHRConstraint constraint = (CHRConstraint)literal.relation; - if(constraint.lastPriorityAdded != Integer.MIN_VALUE) - continue; - constraint.lastPriorityAdded = priority; - ArrayList list = headConstraintMap.get(constraint); - if(list == null) - continue; - for(CHRRule lowerPriorityRule : list) - if(lowerPriorityRule.lastPriorityExecuted == Integer.MIN_VALUE) - calculateLastPriority(headConstraintMap, lowerPriorityRule, priority); - } - } - - private static THashMap> createHeadConstraintMap(CHRRuleset ruleset) { - THashMap> map = new THashMap>(); - for(CHRRule rule : ruleset.rules) - for(CHRLiteral literal : rule.head.literals) - if(literal.relation instanceof CHRConstraint) { - ArrayList list = map.get(literal.relation); - if(list == null) { - list = new ArrayList(); - map.put((CHRConstraint)literal.relation, list); - list.add(rule); - } - else if(list.get(list.size()-1) != rule) - list.add(rule); - } - return map; - } - - private static void printPriorities(CHRRuleset ruleset) { - System.out.println("-------------------------------"); - for(CHRConstraint constraint : ruleset.constraints) { - System.out.print(" [" + constraint.firstPriorityAdded + ".." + constraint.lastPriorityAdded + "]"); - if(constraint.firstPriorityRemoved != Integer.MAX_VALUE) - System.out.print("R[" + constraint.firstPriorityRemoved + ".." + constraint.lastPriorityRemoved + "]"); - System.out.print(" "); - System.out.println(constraint); - } - for(CHRRule rule : ruleset.rules) { - System.out.print(rule.priority); - System.out.print(" [" + rule.firstPriorityExecuted + ".." + rule.lastPriorityExecuted + "] "); - System.out.println(rule); - } - } - - private static void determinePassiveLiterals(CHRRule rule) { - for(CHRLiteral literal : rule.head.literals) { - if(literal.passive) - continue; - CHRConstraint constraint = (CHRConstraint)literal.relation; - if(constraint.lastPriorityAdded < rule.priority) - literal.passive = true; - } - } -} +package org.simantics.scl.compiler.elaboration.chr.analysis; + +import java.util.ArrayList; + +import org.simantics.scl.compiler.elaboration.chr.CHRLiteral; +import org.simantics.scl.compiler.elaboration.chr.CHRRule; +import org.simantics.scl.compiler.elaboration.chr.CHRRuleset; +import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint; + +import gnu.trove.map.hash.THashMap; + +public class UsageAnalysis { + public static void analyzeUsage(CHRRuleset ruleset) { + THashMap> headConstraintMap = createHeadConstraintMap(ruleset); + //calculateFirstPriorities(ruleset, headConstraintMap); + calculateLastPriorities(ruleset, headConstraintMap); + if(!ruleset.extensible) + for(CHRRule rule : ruleset.rules) + determinePassiveLiterals(rule); + //printPriorities(ruleset); + } + /* + private static void calculateFirstPriorities(CHRRuleset ruleset, + THashMap> headConstraintMap) { + for(CHRRule rule : ruleset.rules) + rule.firstPriorityExecuted = Integer.MAX_VALUE; + for(CHRConstraint constraint : ruleset.constraints) { + constraint.firstPriorityAdded = Integer.MAX_VALUE; + constraint.firstPriorityRemoved = Integer.MAX_VALUE; + } + for(CHRRule rule : ruleset.rules) + calculateFirstPriority(headConstraintMap, rule); + } + + private static void calculateFirstPriority(THashMap> headConstraintMap, CHRRule rule) { + int result = rule.priority; + for(CHRLiteral literal : rule.head.literals) + if(literal.relation instanceof CHRConstraint) { + CHRConstraint constraint = (CHRConstraint)literal.relation; + int constraintPriority = constraint.firstPriorityAdded; + if(constraintPriority == Integer.MAX_VALUE) + return; + result = Math.max(result, constraintPriority); + } + rule.firstPriorityExecuted = result; + for(CHRLiteral literal : rule.head.literals) + if(literal.killAfterMatch && literal.relation instanceof CHRConstraint) { + CHRConstraint constraint = (CHRConstraint)literal.relation; + if(constraint.firstPriorityRemoved == Integer.MAX_VALUE) + constraint.firstPriorityRemoved = result; + } + for(CHRLiteral literal : rule.body.literals) + if(literal.relation instanceof CHRConstraint) { + CHRConstraint constraint = (CHRConstraint)literal.relation; + if(constraint.firstPriorityAdded != Integer.MAX_VALUE) + continue; + constraint.firstPriorityAdded = result; + ArrayList list = headConstraintMap.get(constraint); + if(list == null) + continue; + for(CHRRule lowerPriorityRule : list) + if(lowerPriorityRule.priority < rule.priority) + // We know here that previous call to lowerPriorityRule "failed", + // because constraint.firstPriorityAdded was previously Integer.MAX_VALUE + calculateFirstPriority(headConstraintMap, lowerPriorityRule); + } + } + */ + private static void calculateLastPriorities(CHRRuleset ruleset, + THashMap> headConstraintMap) { + for(CHRRule rule : ruleset.rules) + rule.lastPriorityExecuted = Integer.MIN_VALUE; + for(CHRConstraint constraint : headConstraintMap.keySet()) { + constraint.lastPriorityAdded = Integer.MIN_VALUE; + constraint.lastPriorityRemoved = Integer.MIN_VALUE; + } + for(int i=ruleset.rules.size()-1;i>=0;--i) { + CHRRule rule = ruleset.rules.get(i); + if(rule.lastPriorityExecuted == Integer.MIN_VALUE) + calculateLastPriority(headConstraintMap, rule, rule.priority); + } + } + + private static void calculateLastPriority(THashMap> headConstraintMap, + CHRRule rule, int priority) { + rule.lastPriorityExecuted = priority; + for(CHRLiteral literal : rule.head.literals) + if(literal.killAfterMatch && literal.relation instanceof CHRConstraint) { + CHRConstraint constraint = (CHRConstraint)literal.relation; + if(constraint.lastPriorityRemoved == Integer.MIN_VALUE) + constraint.lastPriorityRemoved = priority; + } + for(CHRLiteral literal : rule.body.literals) + if(literal.relation instanceof CHRConstraint) { + CHRConstraint constraint = (CHRConstraint)literal.relation; + if(constraint.lastPriorityAdded != Integer.MIN_VALUE) + continue; + constraint.lastPriorityAdded = priority; + ArrayList list = headConstraintMap.get(constraint); + if(list == null) + continue; + for(CHRRule lowerPriorityRule : list) + if(lowerPriorityRule.lastPriorityExecuted == Integer.MIN_VALUE) + calculateLastPriority(headConstraintMap, lowerPriorityRule, priority); + } + } + + private static THashMap> createHeadConstraintMap(CHRRuleset ruleset) { + THashMap> map = new THashMap>(); + for(CHRRule rule : ruleset.rules) + for(CHRLiteral literal : rule.head.literals) + if(literal.relation instanceof CHRConstraint) { + ArrayList list = map.get(literal.relation); + if(list == null) { + list = new ArrayList(); + map.put((CHRConstraint)literal.relation, list); + list.add(rule); + } + else if(list.get(list.size()-1) != rule) + list.add(rule); + } + return map; + } + + /*private static void printPriorities(CHRRuleset ruleset) { + System.out.println("-------------------------------"); + for(CHRConstraint constraint : ruleset.constraints) { + System.out.print(" [" + constraint.firstPriorityAdded + ".." + constraint.lastPriorityAdded + "]"); + if(constraint.firstPriorityRemoved != Integer.MAX_VALUE) + System.out.print("R[" + constraint.firstPriorityRemoved + ".." + constraint.lastPriorityRemoved + "]"); + System.out.print(" "); + System.out.println(constraint); + } + for(CHRRule rule : ruleset.rules) { + System.out.print(rule.priority); + System.out.print(" [" + rule.firstPriorityExecuted + ".." + rule.lastPriorityExecuted + "] "); + System.out.println(rule); + } + }*/ + + private static void determinePassiveLiterals(CHRRule rule) { + for(CHRLiteral literal : rule.head.literals) { + if(literal.passive) + continue; + CHRConstraint constraint = (CHRConstraint)literal.relation; + if(constraint.lastPriorityAdded < rule.priority) + literal.passive = true; + } + } +}