Exemplo n.º 1
0
    def antecedents(self, ids, ruleNum):
        if ids == "all":
            for Id, c in enumerate(self.db):
                if c is not None:
                    # this is inconsitent now as we get (Id, c) for
                    # "all" but the constraint directly if a list of
                    # ids is provided. I don' have time to fix this
                    # now and probably nobody (also not future me)
                    # will notice as you ever only want the Ids if you
                    # don't know them already.
                    yield (Id, c)
        else:
            for i in ids:
                if i >= len(self.db):
                    raise InvalidProof("Rule %i is trying to access constraint "\
                        "(constraintId %i), which is not derived, yet."\
                        %(ruleNum, i))
                elif i <= -len(self.db):
                    raise InvalidProof("Rule %i is trying to access invalid id "\
                        "(constraintId %i)."\
                        %(ruleNum, len(self.db) + i))

                constraint = self.db[i]
                if constraint is None:
                    raise InvalidProof("Rule %i is trying to access constraint "\
                        "(constraintId %i), that was marked as safe to delete."\
                        %(ruleNum, i))

                yield constraint
Exemplo n.º 2
0
    def check(self, context):
        order = OrderContext.setup(context).activeDefinition

        leftSet = set(order.leftVars)
        rightSet = set(order.rightVars)

        sizes = {len(leftSet), len(rightSet), len(order.leftVars), len(order.rightVars)}
        if len(sizes) != 1:
            raise InvalidProof("Number of variables specified in left and right did not match.")
        if not leftSet.isdisjoint(rightSet):
            raise InvalidProof("Variables specified in left and right are not disjoint.")
Exemplo n.º 3
0
    def compute(self, antecedents, context=None):
        antecedents = list(antecedents)
        stack = list()
        antecedentIt = iter(antecedents)

        it = iter(self.instructions)
        ins = next(it, None)
        while ins is not None:
            if isinstance(ins, int):
                stack.append(next(antecedentIt).copy())
            if isinstance(ins, tuple):
                what = ins[0]
                if what == "l":
                    lit = ins[1]
                    stack.append(context.ineqFactory.litAxiom(lit))
                else:
                    assert (False)
            elif ins == "+":
                second = stack.pop()
                first = stack.pop()
                stack.append(first.add(second))
            elif ins == "*":
                constraint = stack.pop()
                factor = next(it)
                if factor < 0:
                    raise InvalidProof("Multiplication by negative number.")
                stack.append(constraint.multiply(factor))
            elif ins == "d":
                constraint = stack.pop()
                divisor = next(it)
                if divisor <= 0:
                    raise InvalidProof("Division by non positive number.")
                stack.append(constraint.divide(divisor))
            elif ins == "s":
                constraint = stack.pop()
                stack.append(constraint.saturate())
            elif ins == "w":
                nxt = next(it, None)
                assert (nxt[0] == "l")
                lit = nxt[1]
                if lit < 0:
                    logging.warn("Weakening step ignores sign of literals.")
                    lit = abs(lit)
                constraint = stack.pop()
                stack.append(constraint.weaken(lit))

            ins = next(it, None)

        assert len(stack) == 1
        stack[0].contract()
        return stack
Exemplo n.º 4
0
    def compute(self, antecedents, context):
        # context for sub verifier
        svContext = verifier.Context()
        svContext.newIneqFactory = context.newIneqFactory
        svContext.ineqFactory = svContext.newIneqFactory()
        svContext.newPropEngine = context.newPropEngine
        svContext.propEngine = svContext.newPropEngine()
        svContext.ruleCount = getattr(context, "ruleCount", 0)

        self._newParseContext = ParseContext(svContext)


        self.onEnterSubVerifier(context, svContext)

        try:
            verify = verifier.Verifier(
                context = svContext,
                settings = context.verifierSettings)
            verify(context.rules)
        except StopSubVerifier:
            self.exitSubVerifier(context, svContext)
            svContext.propEngine = None
            svContext.ineqFactory = None
        else:
            raise InvalidProof("Subproof not finished.")

        return []
Exemplo n.º 5
0
    def __call__(self, rules):
        self.db = list()
        self.result = VerificationResult()
        self.result.requireUnsat = self.settings.requireUnsat

        if self.settings.trace:
            print()
            print("=== begin trace ===")

        if self.settings.progressBar:
            self.start_time = time.time()

        for ruleNum, rule in enumerate(itertools.chain([DummyRule()], rules)):
            try:
                self.handleRule(ruleNum, rule)
            except InvalidProof as e:
                e.lineInFile = rule.lineInFile
                raise e

        self.result.usesAssumptions = getattr(self.context, "usesAssumptions",
                                              False)
        self.result.containsContradiction = getattr(self.context,
                                                    "containsContradiction",
                                                    False)

        if self.settings.requireUnsat and not self.result.containsContradiction:
            raise InvalidProof("Proof does not contain contradiction!")

        if self.settings.trace:
            print("=== end trace ===")
            print()

        return self.result
Exemplo n.º 6
0
    def __call__(self):
        while self.subgoals:
            nxtGoalId, nxtGoal = self.subgoals.popleft()

            ## for performance reasons the following two checks are
            ## done directly when the effected constraints are computed
            #
            # if self.selfImplication(nxtGoalId, nxtGoal):
            #     continue

            asRhs = nxtGoal.getAsRightHand()
            if asRhs is None:
                asLhs = nxtGoal.getAsLeftHand()

                with TemporaryAttach(self.propEngine) as temporary:
                    for c in asLhs:
                        if c is not None:
                            temporary.attach(c)

                    if self.rupImplication(
                            nxtGoalId, self.context.ineqFactory.fromTerms([],
                                                                          1)):
                        continue

            else:
                nxtGoal = asRhs.copy()
                if nxtGoal.isTrivial():
                    if self.verbose:
                        print(
                            "    automatically proved %s, constraint is trivial."
                            % (str(nxtGoalId)))
                    continue

                if not self.triedRUP and self.rupImplication(
                        None, self.context.ineqFactory.fromTerms([], 1)):
                    self.wasRUP = True
                    break

                self.triedRUP = True

                if self.rupImplication(nxtGoalId, nxtGoal):
                    continue

                # implication checks are stronger if we plug in propagated literals
                asmnt = self.getPropagatedAssignment().get()
                nxtGoal = nxtGoal.substitute(asmnt)

                # this is already checked when the effected constraints
                # are computed. However, due to caching it could be that
                # new constraints were added since then.
                if self.inDB(nxtGoalId, nxtGoal):
                    continue

                if self.dbImplication(nxtGoalId, nxtGoal):
                    continue

            raise InvalidProof("Could not proof proof goal %s automatically." %
                               (str(nxtGoalId)))
Exemplo n.º 7
0
    def antecedents(self, ids, ruleNum):
        if ids == "all":
            for c in self.db:
                if c is not None:
                    yield c
        else:
            for i in ids:
                if i >= len(self.db):
                    raise InvalidProof("Rule %i is trying to access constraint "\
                        "(constraintId %i), which is not derived, yet."\
                        %(ruleNum, i))

                constraint = self.db[i]
                if constraint is None:
                    raise InvalidProof("Rule %i is trying to access constraint "\
                        "(constraintId %i), that was marked as save to delete."\
                        %(ruleNum, i))

                yield constraint
Exemplo n.º 8
0
    def pop(self, checkSubgoals=True):
        oldContext = self.infos.pop()
        for callback in oldContext.callbacks:
            callback(self.context, oldContext)

        if checkSubgoals and len(oldContext.subgoals) > 0:
            for Id, subgoal in oldContext.subgoals.items():
                raise InvalidProof(
                    "Open subgoal not proven: %s: %s" %
                    (str(Id), subgoal.toString(self.context.ineqFactory)))

        return oldContext
Exemplo n.º 9
0
    def parse(cls, words, ineqFactory, forbidden=[]):
        result = cls()

        try:
            nxt = next(words)
        except StopIteration:
            return result

        while nxt != ";":
            frm = ineqFactory.lit2int(nxt)
            if frm < 0:
                raise ValueError("Substitution should only"
                                 "map variables, not negated literals.")
            if frm in forbidden:
                raise InvalidProof("Substitution contains forbidden variable.")

            try:
                nxt = next(words)
                if nxt == "→" or nxt == "->":
                    nxt = next(words)
            except StopIteration:
                raise ValueError("Substitution is missing"
                                 "a value for the last variable.")

            if nxt == "0":
                to = False
            elif nxt == "1":
                to = True
            else:
                to = ineqFactory.lit2int(nxt)

            result.map(frm, to)

            try:
                nxt = next(words)

                if nxt == ",":
                    nxt = next(words)
            except StopIteration:
                break

        return result
Exemplo n.º 10
0
 def check(self):
     if not self.transitivity.isProven:
         raise InvalidProof("Proof did not show transitivity of order.")
Exemplo n.º 11
0
 def check(self, context):
     if not self.order.transitivity.isProven:
         raise InvalidProof("Transitivity proof is missing.")
Exemplo n.º 12
0
 def compute(self, antecedents, context):
     if self.found:
         raise InvalidProof("Constraint should be deleted.")
     return []
Exemplo n.º 13
0
    def check(self, context):
        if not getattr(context, "containsContradiction", False):
            raise InvalidProof("Sub proof did not show contradiction.")

        context.containsContradiction = False
Exemplo n.º 14
0
    def handleRule(self, ruleNum, rule):
        self.checked_rules += 1
        if self.settings.progressBar:
            printProgressBar(ruleNum,
                             self.context.ruleCount,
                             self.start_time,
                             length=50)

        didPrint = False

        antecedents = self.antecedents(rule.antecedentIDs(), ruleNum)
        constraints = rule.compute(antecedents, self.context)

        for constraint in constraints:
            if constraint is None:
                continue

            constraintId = len(self.db)
            constraint = self.attach(constraint, constraintId)
            if self.settings.trace and ruleNum > 0:
                didPrint = True
                self.print(
                    "  ConstraintId ${cid}%(line)03d${reset}: ${ienq}%(ineq)s${reset}"
                    % {
                        "line": constraintId,
                        "ineq": self.context.ineqFactory.toString(constraint)
                    })
            if self.settings.proofGraph is not None and ruleNum > 0:
                ids = rule.antecedentIDs()
                if ids == "all":
                    ids = (i for (i, c) in enumerate(self.db)
                           if c is not None and i > 0)
                f = self.settings.proofGraph
                print("%(ineq)s ; %(line)d = %(antecedents)s" % {
                    "line": constraintId,
                    "ineq": self.context.ineqFactory.toString(constraint),
                    "antecedents": " ".join(map(str, ids))
                },
                      file=f)

            self.db.append(constraint)

        # Delete rule expects delete to happen after compute!
        deletedConstraints = [
            i for i in rule.deleteConstraints() if self.db[i] is not None
        ]
        if self.settings.trace and len(deletedConstraints) > 0:
            didPrint = True
            print("  ConstraintId  - : deleting %(ineq)s" %
                  {"ineq": ", ".join(map(str, deletedConstraints))})

        deleted = dict()
        for i in deletedConstraints:
            ineq = self.db[i]
            if ineq is None:
                continue

            self.db[i] = None
            wasLastReference = self.detach(ineq, i)

            if wasLastReference and ineq.isCoreConstraint:
                if self.settings.isCheckDeletionOn:
                    if not ineq.rupCheck(self.context.propEngine, True):
                        raise InvalidProof(
                            "Could not verify deletion of core constraint %s",
                            self.context.ineqFactory.toString(ineq))
                else:
                    orderContext = getattr(self.context, "orderContext", None)
                    if orderContext is not None and len(
                            orderContext.activeOrder.vars) > 0:
                        if not ineq.rupCheck(self.context.propEngine, True):
                            raise InvalidProof(
                                "Could not verify deletion of core constraint while order was loaded."
                            )

            deleted[id(ineq)] = ineq

        # clean up references, to not get spicious warnings
        constraint = None
        antecedents = None
        for ineq in deleted.values():
            refcount = sys.getrefcount(ineq)
            attachCount = self.context.propEngine.attachCount(ineq)
            if (attachCount == 0 and refcount > 4):
                # todo: refcount should be at-most 3, except for
                # constraints that apear in the formula or in dominance proofs.
                #logging.warning
                print("Internal Warning: refcount of "
                      "deleted constraint too large (is %i), memory will "
                      "not be freed." % (refcount))
                print(self.context.ineqFactory.toString(ineq))
Exemplo n.º 15
0
 def compute(self, antecedents, context):
     try:
         return [context.formula[self._axiomId - 1]]
     except IndexError as e:
         raise InvalidProof("Trying to load non existing axiom.")
Exemplo n.º 16
0
 def compute(self, antecedents, context=None):
     if (len(context.formula) != self._numConstraints):
         raise InvalidProof("Wrong number of constraints")
     return context.formula