'''
Created on Sep 6, 2015

@author: levi
'''

from util.ecore_utils import *

class Prunner(object):
    '''
    checks whether a path condition can be removed from the set of path conditions being built
    based on the fact that missing containment relations cannot be built by the rules that are
    left to symbolically execute
    '''

    def __init__(self, metamodel, transformation):
        '''
        Constructor
        '''
        self.eu = EcoreUtils(metamodel)
        self.mmContainmentLinks = self.eu.getContaimentLinksForClasses()
        
        self.ruleContainmentLinks = {}
        for layer in transformation:
            for rule in layer:
                self.ruleContainmentLinks[rule.name] = self.eu.getBuiltContainmentLinks(rule)              
        

    def getContainmentLinksBuiltByRuleSet(self, ruleNames):
        '''
        get all the containment links built by a set of rules
        '''
        builtContainmentLinks = {}
        for ruleName in ruleNames:
            builtContainmentLinks.update(self.ruleContainmentLinks[ruleName])
            
        return builtContainmentLinks


    def getClassesLinksBuiltByRuleSet(self, ruleNames):
        '''
        get all the classes built by a set of rules
        '''
        builtClasses = []
        for ruleName in ruleNames:
            builtClasses.extend(self.ruleClasses[ruleName])
            
        return builtClasses


    def isPathConditionStillFeasible(self, pathCondition, rulesToTreat):
        '''
        decide whether a path condition can be removed from the path condition set because the
        containment requirements cannot be fulfilled
        '''
        missingContLinks = self.eu.getMissingContainmentLinks(pathCondition)
        
#         print("Path condition: " + pathCondition.name)   
#         print("Missing containment links: " + str(missingContLinks))                     
                
        contLinksInRulesToTreat = self.getContainmentLinksBuiltByRuleSet(rulesToTreat)
        
#         print("Containment links in rules to treat: " + str(contLinksInRulesToTreat))   
        
        allMissingContLinksFound = True 
                
        for className in missingContLinks.keys():
            if className not in contLinksInRulesToTreat.keys():
                allMissingContLinksFound = False
                break
            elif set(missingContLinks[className]).intersection(set([contLinksInRulesToTreat[className]])) == set():
                allMissingContLinksFound = False
                break
        
        if allMissingContLinksFound:
            return True
        else: 
            return False
        
        
        
                
        
        
@@ -422,32 +422,61 @@
 tor%0A        '''%0A
+%0A        self.debug = False%0A%0A
         self.eu 
@@ -781,16 +781,18 @@
 ks(rule)
+%0A%0A
         
@@ -789,32 +789,194 @@
 %0A%0A              
+  if self.debug:%0A                    print(%22Rule containment links: %22 + rule.name + %22 = %22 + str(self.ruleContainmentLinks%5Brule.name%5D))%0A%0A        #raise Exception()
 %0A        %0A%0A    d
@@ -1849,32 +1849,164 @@
 led%0A        '''%0A
+%0A%0A        #if this is the last layer, then do not prune these path conditions%0A        if not rulesToTreat:%0A            return True%0A%0A
         missingC
@@ -2066,24 +2066,25 @@
 dition)%0A
+%0A
         
 %0A#      
@@ -2067,34 +2067,50 @@
 ition)%0A%0A        
-%0A#
+if self.debug:%0A   
          print(%22
@@ -2148,21 +2148,20 @@
 on.name)
+%0A
    
-%0A#
         
@@ -2225,29 +2225,8 @@
 ks))
-                     
 %0A   
@@ -2335,17 +2335,146 @@
        %0A
-#
+        if self.debug:%0A            print(%22Rules to treat: %22)%0A            for rule in rulesToTreat:%0A                print(rule)%0A   
         
@@ -2551,19 +2551,16 @@
 oTreat))
-   
 %0A       
@@ -2796,32 +2796,33 @@
           break%0A
+%0A
             elif
@@ -2821,17 +2821,34 @@
     
-elif set(
+links = %5Blink for link in 
 miss
@@ -2874,74 +2874,73 @@
 ame%5D
-).intersection(set(%5BcontLinksInRulesToTreat%5BclassName%5D%5D)) == set()
+ if link in missingContLinks%5BclassName%5D%5D%0A            if not links
 :%0A  

Fix error in prunner. Also added some debugging.