Esempio n. 1
0
def op_card(arg):
    '''
    :param arg:
    :type left: :class:`~arg`
    :param right:
    :type right: :class:`~ExprArg`
    :returns: :class:`~IntArg` 
    
    Returns the number of instances that are *on* in arg.
    '''
    assert isinstance(arg, ExprArg)

    instances = []
    matches = getSetInstancePairs(arg)
    known_card = 0
    if arg.getInts():
        card_cons = compute_int_set(arg.getInts())
        for i in card_cons:
            if isinstance(i, SMTLib.SMT_BoolConst):
                if i.value:
                    known_card = known_card + 1
            else:
                instances.append(
                    SMTLib.SMT_If(i, SMTLib.SMT_IntConst(1),
                                  SMTLib.SMT_IntConst(0)))
    for (instance, _) in matches.values():
        (expr, polarity) = instance
        if polarity == Common.DEFINITELY_ON:
            known_card = known_card + 1
        else:
            instances.append(
                SMTLib.SMT_If(expr, SMTLib.SMT_IntConst(1),
                              SMTLib.SMT_IntConst(0)))
    instances.append(SMTLib.SMT_IntConst(known_card))
    return IntArg(SMTLib.createSum(instances))
Esempio n. 2
0
def op_difference(left, right):
    '''
    :param left:
    :type left: :class:`~ExprArg`
    :param right:
    :type right: :class:`~ExprArg`
    :returns: :class:`~ExprArg` 
    
    Computes the set difference (left - - right)
    '''
    assert isinstance(left, ExprArg)
    assert isinstance(right, ExprArg)
    if left.getInts() or right.getInts():
        sys.exit("FIXME ints diff")
    matches = getSetInstancePairs(left, right)
    newInstances = {}
    for (sort, index) in matches.keys():
        key = (sort, index)
        ((lexpr, lpol), (rexpr, rpol)) = matches[(sort, index)]
        if rpol == Common.DEFINITELY_ON or lpol == Common.DEFINITELY_OFF:
            #cases (-1, -1), (-1, 0), (-1, 1), (0, 1), (1, 1)
            continue
        elif rpol == Common.DEFINITELY_OFF:
            #cases (0 , -1), (1, -1)
            newInstances[key] = (lexpr, lpol)
        else:
            #rpol is unknown, lpol is unknown or on => new_pol is UNKNOWN
            #cases (0, 0), (1, 0)
            #if right is not on, then left, else sort.isOff
            new_expr = SMTLib.SMT_If(SMTLib.createNot(rexpr), lexpr,
                                     sort.parentInstances)
            newInstances[key] = (new_expr, Common.UNKNOWN)
    return ExprArg(newInstances)
Esempio n. 3
0
def putIfNotMatched(sort, mask, index, value, matches):
    '''
    Used to make sure you don't add duplicate elements to a set i.e. a sub and super.
    Needed by union, intersection, and difference.
    '''
    if not matches:
        mask.put(index, value)
    else:
        cond = []
        for i in matches:
            (leftIsSub, transform, (match_sort, match_mask)) = i
            if leftIsSub:
                if match_mask.get(index + transform):
                    cond.append(
                        match_sort.isOff(match_mask.get(index + transform)))
            else:
                if match_mask.get(index - transform):
                    cond.append(
                        match_sort.isOff(match_mask.get(index - transform)))
        if not cond:
            mask.put(index, value)
        else:
            mask.put(
                index,
                SMTLib.SMT_If(mAnd(*cond), value,
                              SMTLib.SMT_IntConst(sort.parentInstances)))
Esempio n. 4
0
def quant_one(exprs, ifConstraints):
    '''
    There's probably a better way to do this.
    '''
    condList = getQuantifierConditionList(exprs)
    if ifConstraints:
        condList = [mAnd(i, j) for i, j in zip(ifConstraints, condList)]
    exprList = []
    for i in range(len(condList)):
        exprList.append(
            SMTLib.SMT_If(condList[i], SMTLib.SMT_IntConst(1),
                          SMTLib.SMT_IntConst(0)))
    return SMTLib.SMT_EQ(SMTLib.createSum(*exprList), SMTLib.SMT_IntConst(1))
Esempio n. 5
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)))
Esempio n. 6
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])))
Esempio n. 7
0
def max2(l, r):
    '''
    returns the min of two integers
    '''
    return SMTLib.SMT_If(SMTLib.SMT_LE(l, r), r, l)