예제 #1
0
    def addGroupCardConstraints(self):
        self.upperGCard = self.element.gcard.interval[1].value
        self.lowerGCard = self.element.gcard.interval[0].value
        if (len(self.fields) == 0
                and ((not self.superSort) or self.superSort.fields == 0)):
            return
        #lower bounds
        if not self.fields:
            return  # front end is broken
        if self.lowerGCard == 0 and self.upperGCard == -1:
            return
        for i in range(self.numInstances):

            bigSumm = SMTLib.SMT_IntConst(0)
            for j in self.fields:
                bigSumm = SMTLib.SMT_Plus(bigSumm, j.summs[i])
            #**** LEAVE THIS CODE ****
            #don't include inherited fields for now
            #if self.superSort:
            #    for j in self.superSort.fields:
            #        print("found " + str(j))
            #        bigSumm = bigSumm +  j.summs[i + self.indexInSuper]
            if self.lowerGCard != 0:
                self.constraints.addGroupCardConstraint(
                    SMTLib.SMT_Implies(
                        self.isOn(i),
                        SMTLib.SMT_GE(bigSumm,
                                      SMTLib.SMT_IntConst(self.lowerGCard))))
            if self.upperGCard != -1:
                self.constraints.addGroupCardConstraint(
                    SMTLib.SMT_Implies(
                        self.isOn(i),
                        SMTLib.SMT_LE(bigSumm,
                                      SMTLib.SMT_IntConst(self.upperGCard))))
예제 #2
0
 def createCardinalityConstraints(self):
     if not self.cfr.isUsed(self.element):
         return
     self.summs = [[] for i in range(self.parentInstances + 1)]
     for i in range(self.numInstances):
         (lower, upper, _) = self.getInstanceRange(i)
         for j in range(lower, upper + 1):
             self.summs[j].append(
                 SMTLib.SMT_If(
                     SMTLib.SMT_EQ(self.instances[i],
                                   SMTLib.SMT_IntConst(j)),
                     SMTLib.SMT_IntConst(1), SMTLib.SMT_IntConst(0)))
     for i in range(len(self.summs)):
         if self.summs[i]:
             self.summs[i] = SMTLib.createSum(*[self.summs[i]])
         else:
             self.summs[i] = SMTLib.SMT_IntConst(0)
     for i in range(self.parentInstances):
         if self.parent:
             self.constraints.addCardConstraint(
                 SMTLib.SMT_Implies(
                     self.parent.isOn(i),
                     SMTLib.SMT_GE(
                         self.summs[i],
                         SMTLib.SMT_IntConst(self.lowerCardConstraint))))
             if self.upperCardConstraint != -1:
                 self.constraints.addCardConstraint(
                     SMTLib.SMT_Implies(
                         self.parent.isOn(i),
                         SMTLib.SMT_LE(
                             self.summs[i],
                             SMTLib.SMT_IntConst(
                                 self.upperCardConstraint))))
         else:
             self.constraints.addCardConstraint(
                 SMTLib.SMT_GE(
                     self.summs[i],
                     SMTLib.SMT_IntConst(self.lowerCardConstraint)))
             if self.upperCardConstraint != -1:
                 self.constraints.addCardConstraint(
                     SMTLib.SMT_LE(
                         self.summs[i],
                         SMTLib.SMT_IntConst(self.upperCardConstraint)))
예제 #3
0
 def ConstraintMustDominatesX(self, model):
     """
     Returns a constraint that a new instance has to be better than the instance represented by model in at least one dimension, 
     and better or equal in all the other ones.
     """
     dominationDisjunction = []
     i = 0
     for dominatedByMetric in self.metrics_variables:
         dominationConjunction = []
         j = 0
         if self.metrics_objective_direction[i] == Common.METRICS_MAXIMIZE:
             dominationConjunction.append(
                 SMTLib.SMT_GT(
                     dominatedByMetric,
                     SMTLib.SMT_IntConst(
                         Common.evalForNum(
                             model,
                             dominatedByMetric.convert(
                                 self.cfr.solver.converter)))))
         else:
             dominationConjunction.append(
                 SMTLib.SMT_LT(
                     dominatedByMetric,
                     SMTLib.SMT_IntConst(
                         Common.evalForNum(
                             model,
                             dominatedByMetric.convert(
                                 self.cfr.solver.converter)))))
         for AtLeastEqualInOtherMetric in self.metrics_variables:
             if j != i:
                 if self.metrics_objective_direction[
                         j] == Common.METRICS_MAXIMIZE:
                     dominationConjunction.append(
                         SMTLib.SMT_GE(
                             AtLeastEqualInOtherMetric,
                             SMTLib.SMT_IntConst(
                                 Common.evalForNum(
                                     model,
                                     AtLeastEqualInOtherMetric.convert(
                                         self.cfr.solver.converter)))))
                 else:
                     dominationConjunction.append(
                         SMTLib.SMT_LE(
                             AtLeastEqualInOtherMetric,
                             SMTLib.SMT_IntConst(
                                 Common.evalForNum(
                                     model,
                                     AtLeastEqualInOtherMetric.convert(
                                         self.cfr.solver.converter)))))
             j = 1 + j
         i = 1 + i
         dominationDisjunction.append(
             SMTLib.SMT_And(*dominationConjunction))
     constraintDominateX = SMTLib.SMT_Or(*dominationDisjunction)
     return constraintDominateX
예제 #4
0
    def createInstancesConstraintsAndFunctions(self):
        for i in range(self.numInstances):
            (lower, upper, extraAbsenceConstraint) = self.instanceRanges[i]
            #lower == upper case (simpler)
            if lower == upper:
                constraint = SMTLib.SMT_EQ(self.instances[i],
                                           SMTLib.SMT_IntConst(upper))
                if extraAbsenceConstraint:
                    self.constraints.addInstanceConstraint(
                        SMTLib.SMT_Or(self.isOff(i), constraint))
                else:
                    #TODO self.instances[i] = SMTLib.SMT_IntConst(lower)
                    self.constraints.addInstanceConstraint(constraint)
            else:
                #parent pointer is >= lower
                self.constraints.addInstanceConstraint(
                    SMTLib.SMT_GE(self.instances[i],
                                  SMTLib.SMT_IntConst(lower)))
                constraint = SMTLib.SMT_LE(self.instances[i],
                                           SMTLib.SMT_IntConst(upper))
                if extraAbsenceConstraint:
                    #parent pointer is <= upper , or equal to parentInstances
                    self.constraints.addInstanceConstraint(
                        SMTLib.SMT_Or(self.isOff(i), constraint))
                else:
                    #parent pointer is <= upper
                    self.constraints.addInstanceConstraint(constraint)

            #sorted parent pointers (only consider things that are not part of an abstract)
            if not self.beneathAnAbstract:
                if i != self.numInstances - 1:
                    self.constraints.addInstanceConstraint(
                        SMTLib.SMT_LE(self.instances[i],
                                      self.instances[i + 1]))
        if not self.parent:
            return
        #if the parent is not live, then no child can point to it
        for i in range(self.parent.numInstances):
            for j in range(self.numInstances):
                self.constraints.addInstanceConstraint(
                    SMTLib.SMT_Implies(
                        self.parent.isOff(i),
                        SMTLib.SMT_NE(self.instances[j],
                                      SMTLib.SMT_IntConst(i))),
                    self.parent.known_polarity(i, local=True) !=
                    Common.DEFINITELY_ON)
예제 #5
0
    def addRefConstraints(self):
        if not self.refSort:
            return
        elif isinstance(self.refSort,
                        PrimitiveType) and self.refSort.type == "real":
            self.refs = SMTLib.SMT_RealVector(self.element.uid + "_ref",
                                              self.numInstances)
        elif isinstance(self.refSort, PrimitiveType):
            self.refs = SMTLib.SMT_IntVector(self.element.uid + "_ref",
                                             self.numInstances)
        else:
            self.refs = SMTLib.SMT_IntVector(
                self.element.uid + "_ref",
                self.numInstances,
                bits=self.getBits(self.refSort.parentInstances + 1))

        if not isinstance(self.refSort, PrimitiveType):
            for i in range(self.numInstances):
                #refs pointer is >= 0
                self.constraints.addRefConstraint(
                    SMTLib.SMT_GE(self.refs[i], SMTLib.SMT_IntConst(0)))
                #ref pointer is <= upper card of ref parent
                self.constraints.addRefConstraint(
                    SMTLib.SMT_LE(
                        self.refs[i],
                        SMTLib.SMT_IntConst(self.refSort.numInstances)))
        #if integer refs, zero out refs that do not have live parents,
        #if clafer refs, set equal to ref.parentInstances if not live

        #reference symmetry breaking
        if not self.element.isAbstract:
            for i in range(self.numInstances - 1):
                for j in range(i + 1, self.numInstances):
                    if isinstance(self.refSort, PrimitiveType):
                        self.constraints.addRefConstraint(
                            SMTLib.SMT_Implies(
                                SMTLib.SMT_EQ(self.instances[i],
                                              self.instances[j]),
                                SMTLib.SMT_LE(self.refs[i], self.refs[j])))
                    else:
                        self.constraints.addRefConstraint(
                            SMTLib.SMT_Implies(
                                mAnd(
                                    SMTLib.SMT_NE(
                                        self.refs[i],
                                        SMTLib.SMT_IntConst(
                                            self.refSort.numInstances)),
                                    SMTLib.SMT_EQ(self.instances[i],
                                                  self.instances[j])),
                                SMTLib.SMT_LE(self.refs[i], self.refs[j])))

        for i in range(self.numInstances):
            if isinstance(self.refSort, PrimitiveType):
                if self.refSort == "integer":
                    self.constraints.addRefConstraint(
                        SMTLib.SMT_Implies(
                            self.isOff(i),
                            SMTLib.SMT_EQ(self.refs[i],
                                          SMTLib.SMT_IntConst(0))),
                        self.known_polarity(i, local=True) !=
                        Common.DEFINITELY_ON)
                elif self.refSort == "string":
                    if Options.STRING_CONSTRAINTS:
                        self.constraints.addRefConstraint(
                            SMTLib.SMT_Implies(
                                self.isOff(i),
                                SMTLib.SMT_EQ(self.refs[i],
                                              self.cfr.EMPTYSTRING)),
                            self.known_polarity(i, local=True) !=
                            Common.DEFINITELY_ON)
                    else:
                        self.constraints.addRefConstraint(
                            SMTLib.SMT_Implies(
                                self.isOff(i),
                                SMTLib.SMT_EQ(self.refs[i],
                                              SMTLib.SMT_IntConst(0))),
                            self.known_polarity(i, local=True) !=
                            Common.DEFINITELY_ON)
                else:
                    self.constraints.addRefConstraint(
                        SMTLib.SMT_Implies(
                            self.isOff(i),
                            SMTLib.SMT_EQ(self.refs[i],
                                          SMTLib.SMT_IntConst(0))),
                        self.known_polarity(i, local=True) !=
                        Common.DEFINITELY_ON)
            else:
                if self.known_polarity(i, local=True) != Common.DEFINITELY_ON:
                    self.constraints.addRefConstraint(
                        SMTLib.SMT_If(
                            self.isOff(i),
                            SMTLib.SMT_EQ(
                                self.refs[i],
                                SMTLib.SMT_IntConst(
                                    self.refSort.numInstances)),
                            SMTLib.SMT_NE(
                                self.refs[i],
                                SMTLib.SMT_IntConst(
                                    self.refSort.numInstances))))
                else:
                    self.constraints.addRefConstraint(
                        SMTLib.SMT_NE(
                            self.refs[i],
                            SMTLib.SMT_IntConst(self.refSort.numInstances)))
                #if refsort.full does not exist, create it
                if not self.refSort.full:
                    self.refSort.full = lambda x: mOr(*[
                        SMTLib.SMT_And(
                            SMTLib.SMT_EQ(x, SMTLib.SMT_IntConst(i)),
                            self.refSort.isOn(i))
                        for i in range(self.refSort.numInstances)
                    ])
                #the clafer that the reference points to must be "on"
                self.constraints.addRefConstraint(
                    SMTLib.SMT_Implies(
                        SMTLib.SMT_NE(
                            self.refs[i],
                            SMTLib.SMT_IntConst(self.refSort.numInstances)),
                        self.refSort.full(self.refs[i])))