def exec_weakin(self, envr, pm): result = ProofResult("") result.source = self if len(self.args) != 1: raise ProofError("weakin takes one argument, found: " + str(len(self.args))) intest = self.resolveOrDont(self.args[0]) if not isinstance(intest, judge.InTest) or intest.nt: raise ProofError("weakin expects a positive contains assertion, found: " + intext.shortString()) cc = intest.rhs if not isinstance(cc, expSemantics.Concat) or len(cc.elements) != 2: raise ProofError("weakin expects a concatenation of length 2, found: " + cc.shortString()) cc2 = expSemantics.Concat(None) cc2.elements.append(cc.elements[0]) cc2.elements.append(envr.fresh(cc.elements[0])) cc2.elements.append(cc.elements[1]) cc2.typeF = cc.typeF in2 = judge.InTest(None) in2.rhs = cc2 in2.nt = False in2.lhs = intest.lhs forall = expSemantics.Forall(None) forall.qVars = [cc2.elements[1]] forall.rhs = in2 self.results = [forall] result.verbose = pm.getIndent() + "weakening: " + self.results[0].shortString() return result
def exec_inconcat(self, envr, pm): result = ProofResult("") result.source = self if len(self.args) != 1: raise ProofError("inconcat takes one argument, found: " + str(len(self.args))) arg = self.resolveOrDont(self.args[0]) if isinstance(arg, expSemantics.Or) and arg.elements: nt = False elif isinstance(arg, expSemantics.And) and arg.elements: nt = True else: raise ProofError("inconcat expects a non-empty conjuntion or disjuntion, found: " + arg.shortString()) fail = [] lhs = arg.elements[0].lhs for e in arg.elements: if not isinstance(e, judge.InTest) or e.nt != nt or e.lhs != lhs: fail.append(e) if fail: raise ProofError("inconcat expects homogenous contains assertions, found: " + "; ".join(map(lambda e: e.shortString(), fail))) r = judge.InTest(None) r.nt = nt r.lhs = lhs r.rhs = expSemantics.Concat(None) r.rhs.elements = map(lambda e: e.rhs, arg.elements) r.rhs.typeF = util.maxListType(map(lambda x: x.rhs.type(pm.world.symList), arg.elements), pm.world.symList) self.results = [r] result.verbose = pm.getIndent() + self.results[0].shortString() return result
def exec_minconcat(self, envr, pm): result = ProofResult("") result.source = self if len(self.args) != 1: raise ProofError("-inconcat takes one argument, found: " + str(len(self.args))) intest = self.resolveOrDont(self.args[0]) if not isinstance(intest, judge.InTest): raise ProofError("-inconcat expects a contains assertion, found: " + intext.shortString()) cc = intest.rhs if not isinstance(cc, expSemantics.Concat): raise ProofError("-inconcat expects a concatenation, found: " + cc.shortString()) els = [] for c in cc.elements: i2 = judge.InTest(None) i2.nt = intest.nt i2.lhs = intest.lhs i2.rhs = c els.append(i2) if intest.nt: r = expSemantics.And(None) else: r = expSemantics.Or(None) r.elements = els self.results = [r] result.verbose = pm.getIndent() + self.results[0].shortString() return result
def exec_mfun(self, envr, pm): result = ProofResult("") result.source = self if len(self.args) != 1: raise ProofError("-fun takes one argument, found: " + str(len(self.args))) eq = self.resolveOrDont(self.args[0]) if not isinstance(eq, judge.Equality): raise ProofError("-fun expects an equality, found: " + str(eq)) funapp = eq.lhs r = eq.rhs if not isinstance(funapp, expSemantics.FunApp): raise ProofError("-fun expects a function application on the lhs, found: " + funapp.shortString()) fun = funapp.fun fType = util.isFunType(fun.type(pm.world.symList), pm.world.symList) if not fType or not hasattr(funapp, "funInfo") or not funapp.funInfo: raise ProofError("-fun can only operate on mappings, found: " + fun.shortString()) l = funapp.args[0] mapping = None for c in funapp.funInfo.cases: if isinstance(c.syntax[0], symbol.List): mapPattern = c.syntax[0].arg ms = [symbol.IdMatch(fType.lhs[0], l), symbol.IdMatch(fType.rhs, r)] mapping = mapPattern.substMatch(ms) if not mapping: raise ProofError("Could not deconstruct function: " + fun.shortString()) funok = expSemantics.FunOK(None) funok.rhs = fun inMap = judge.InTest(None) inMap.rhs = fun inMap.lhs = mapping inMap.nt = False self.results = [inMap, funok] result.verbose = pm.getIndent() + "function elimination: " + "; ".join(map(lambda x: x.shortString(), self.results)) return result
def subst(self, new, old, envr, symbols): if isinstance(old, List): result = List(None) result.arg = self.arg.subst(new.arg, old.arg, envr, symbols) return result else: #check for not in constraints cnstr = judge.InTest(None) cnstr.nt = True cnstr.lhs = old cnstr.rhs = self if envr.proves(cnstr): return self def dvHelper(x): #take into account bound vars xeq = [x] envr.envClosure(xeq) if reduce(lambda x, y: x or y, map(lambda x: envr.isBoundVar(x), xeq), False): return [] if isinstance(x, Id): return x.symbol.deepVars() elif isinstance(x, List): return dvHelper(x.arg) return [] dv = sum(map(dvHelper, self.vars()), []) sym = old if isinstance(old, Symbol) else old.symbol if not envr.provesIn(sym, dv): return self result = Subst(None) result.body = self result.lhs = new result.rhs = old return result
def subst(var, symbols): st = SubstTable(var) for s in symbols: for c in s.cases: if var in c.deepVars(): cc = renameForFresh(c, var.variable) cc.case = c cc.caseMatch = cc.isSuperType(c, symbols) vs = varInBinding(var, c.bindings) if vs: for b in vs: e = env.Env() cnstr = judge.InTest(None) cnstr.nt = False cnstr.lhs = var cnstr.rhs = b[0] e[var] = cnstr st.addCase(s, cc, cc.subst(var.variable, var, e, symbols), "where " + str(var) + " in " + str(b[0])) cnstr.nt = True st.addCase( s, cc, cc.subst(var.variable, var, e, symbols), "where " + str(var) + " not in " + str(b[0])) else: st.addCase(s, cc, cc.subst(var.variable, var, env.Env(), symbols)) if var == c: fast = ast.Ast(ast.ID, None) fast.val = var.name fast.mod = "'" fresh = symbol.Id(fast, c.parent) fresh.repr = None st.addCase(s, fresh, fresh) return st