def calcFreeVars(self): premVars = sum(map(lambda p: p.vars(), self.premises), []) concVars = sum(map(lambda c: c.vars(), self.conclusion), []) self.free = [] for v in premVars: if util.interestingRoot(v) and v not in concVars and v not in self.free: self.free.append(v) self.freeConc = [] for v in concVars: if util.interestingRoot(v) and v not in premVars and v not in self.freeConc: self.freeConc.append(v)
def freshOld(self, clone): if not util.interestingRoot(clone): return clone if isinstance(clone, symbol.Id): result = symbol.FreshId(clone.symbol, self.getFreshNum(clone.name)) result.name = clone.name return result elif isinstance(clone, symbol.List): result = symbol.List(None) result.arg = self.freshOld(clone.arg) return result elif isinstance(clone, symbol.Symbol): return symbol.FreshId(clone, self.getFreshNum(clone.shortString())) elif isinstance(clone, symbol.Seq): result = symbol.Seq(None) result.syntax = map(lambda x: self.freshOld(x), clone.syntax) return result else: print "Error: can't clone " + str(clone) return symbol.ErrSym()
def fresh(self, clone, listDepth = 0): if not util.interestingRoot(clone): return clone if isinstance(clone, symbol.Id): result = symbol.Id(None, clone.symbol) result.name = clone.name result = self.makeFresh(result, listDepth) elif isinstance(clone, symbol.Symbol): result = self.makeFresh(symbol.Id(None, clone), listDepth) elif isinstance(clone, symbol.List): result = symbol.List(None) result.arg = self.fresh(clone.arg, listDepth + 1) elif isinstance(clone, symbol.Seq): result = symbol.Seq(None) result.syntax = map(lambda x: self.fresh(x, listDepth), clone.syntax) else: print "Error: can't clone " + str(clone) return symbol.ErrSym() if listDepth == 0: self.regVars.add(result) return result
def fresh(self, clone, listDepth=0): if not util.interestingRoot(clone): return clone if isinstance(clone, symbol.Id): result = symbol.Id(None, clone.symbol) result.name = clone.name result = self.makeFresh(result, listDepth) elif isinstance(clone, symbol.Symbol): result = self.makeFresh(symbol.Id(None, clone), listDepth) elif isinstance(clone, symbol.List): result = symbol.List(None) result.arg = self.fresh(clone.arg, listDepth + 1) elif isinstance(clone, symbol.Seq): result = symbol.Seq(None) result.syntax = map(lambda x: self.fresh(x, listDepth), clone.syntax) else: print "Error: can't clone " + str(clone) return symbol.ErrSym() if listDepth == 0: self.regVars.add(result) return result
def invertArg(self, arg, envr, pm): arg = self.resolveOrDont(arg) if not isinstance(arg, judge.Judge) or arg.nt: raise ProofError("Argument to " + self.command + " must be a positive judgement, found: " + arg.shortString()) #if any of the parts of arg are not atomic, we will need to use proxy variables proxy = judge.Judge(None) pMatches = [] proxy.defn = arg.defn proxy.nt = False trackFresh = set() def proxify(x): if util.isAtomic(x): return x else: fresh = envr.fresh(x.type(pm.world.symList)) trackFresh.add(fresh) pMatches.append(x.isSuperType(fresh, pm.world.symList)) return fresh proxy.envs = map(proxify, arg.envs) proxy.args = map(proxify, arg.args) #find the cases that match syntactically cases = [] matches2 = [] #matches formals to fresh variables matches = [] #matches fresh variables to actuals for c in proxy.defn.cases: m2 = symbol.SeqMatch(None) for source in set(c.getConclusions()[0].vars()): for v in source.vars(): if util.interestingRoot(v): m2.addIdMatch(v, envr.fresh(v)) m = proxy.unify(c.getConclusions()[0].substMatch([m2]), pm.world.symList) if m: cases.append(c) m.substMatch(pMatches) matches.append(m) matches2.append(m2) #if no cases, then we have a contradiction and the result is false if not cases: return None #use fresh variables for fv for c,m in zip(cases, matches2): for f in c.free: m.addIdMatch(f, envr.fresh(f)) #find the premises of those cases, subst variables deduced from conc prems = map(lambda (c,m,m2): map(lambda p: p.substMatch([m2]).substMatch([m]), c.premises), zip(cases, matches, matches2)) for (p, m, m2) in zip(prems, matches, matches2): for source in set(m.dom()): #account for equalities between actuals and formals of the conclusion/arg if not util.isAtomic(source): pe = judge.Equality(None) pe.lhs = m.match(source) pe.rhs = source.substMatch([m2]).substMatch([m]) pe.nt = False p.insert(0, pe) #account for where refinements of actuals would otherwise be lost elif not source.substMatch([m]).isSuperType(source, pm.world.symList): #revert the premises to using the more refined variable for i in range(len(p)): p[i] = p[i].substMatch([symbol.IdMatch(m.match(source), source.substMatch([m2]))]) #add an equality which captures the refinement pe = judge.Equality(None) pe.lhs = m.match(source) pe.rhs = source.substMatch([m2]) pe.nt = False p.insert(0, pe) return prems,cases
def checkJCase(self, ast, parent, index): result = JCase(ast) result.parent = parent if ast.label: result.label = ast.label else: result.label = parent.name + str(index) result.name = result.label #store the shape as a mapping from the parent envs/args to the case ones #check the shape matches the parent shape if len(ast.val.envs) != len(parent.envs): self.addErr("Incorrect number of environments in case " + result.label + " of " + parent.name, ast.val) result.envs = [] else: m = map(lambda (x, p): self.checkShapeElement(x, p), zip(ast.val.envs, parent.envLabels)) result.envs, result.envMatches = ([ a for a,b in m ], [ b for a,b in m ]) if len(ast.val.children) != len(parent.args): self.addErr("Incorrect number of arguments in case " + result.label + " of " + parent.name, ast.val) result.args = [] else: m = map(lambda (x, p): self.checkShapeElement(x, p), zip(ast.val.children, parent.argLabels)) result.args, result.argMatches = ([ a for a,b in m ], [ b for a,b in m ]) vars = [] #collect all vars in the premises #rename non-unique variables and add corresponding equality constraints names = dict() curEnv = env.Env() for i in range(len(result.envs)): e = result.envs[i] if e in names and e.vars(): result.envs[i] = curEnv.freshOld(e) result.envMatches[i] = result.envs[i].isSuperType(parent.envLabels[i], self.world.symList) p = judge.Equality(None) p.nt = False p.lhs = e p.rhs = result.envs[i] vars.append(p.lhs) vars.append(p.rhs) result.premises.append(p) else: names[e] = e for i in range(len(result.args)): a = result.args[i] if a in names and a.vars(): result.args[i] = curEnv.freshOld(a) result.argMatches[i] = result.args[i].isSuperType(parent.argLabels[i], self.world.symList) p = judge.Equality(None) p.nt = False p.lhs = a p.rhs = result.args[i] vars.append(p.lhs) vars.append(p.rhs) result.premises.append(p) else: names[a] = a #store and check the premises for p in ast.children: sp = self.checkPremise(p) if sp: result.premises.append(sp) vars.extend(sp.vars()) #collect together vars bound in the conclusion bound = [] bound.extend(filter(lambda x: util.interestingRoot(x), sum(map(lambda x: x.vars(), result.envs), []))) bound.extend(filter(lambda x: util.interestingRoot(x), sum(map(lambda x: x.vars(), result.args), []))) result.bound = [] result.globals = [] result.freeConc = [] for b in bound: if b not in result.bound: result.bound.append(b) #check if they are bound in the premises if util.interestingRoot(b) and b not in vars and b not in result.freeConc: result.freeConc.append(b) elif self.globalRoot(b) and b not in result.globals: result.globals.append(b) #compute the free vars (variables that are used in the premises, but not the conc) result.free = [] for b in vars: if util.interestingRoot(b) and b not in result.free and b not in result.bound: result.free.append(b) elif self.globalRoot(b) and b not in result.globals: result.globals.append(b) parent.cases.append(result) if result.label in self.world.jCases: self.addErr("Case " + result.label + " already defined", ast) else: self.world.jCases[result.label] = result
def checkJCase(self, ast, parent, index): result = JCase(ast) result.parent = parent if ast.label: result.label = ast.label else: result.label = parent.name + str(index) result.name = result.label #store the shape as a mapping from the parent envs/args to the case ones #check the shape matches the parent shape if len(ast.val.envs) != len(parent.envs): self.addErr( "Incorrect number of environments in case " + result.label + " of " + parent.name, ast.val) result.envs = [] else: m = map(lambda (x, p): self.checkShapeElement(x, p), zip(ast.val.envs, parent.envLabels)) result.envs, result.envMatches = ([a for a, b in m], [b for a, b in m]) if len(ast.val.children) != len(parent.args): self.addErr( "Incorrect number of arguments in case " + result.label + " of " + parent.name, ast.val) result.args = [] else: m = map(lambda (x, p): self.checkShapeElement(x, p), zip(ast.val.children, parent.argLabels)) result.args, result.argMatches = ([a for a, b in m], [b for a, b in m]) vars = [] #collect all vars in the premises #rename non-unique variables and add corresponding equality constraints names = dict() curEnv = env.Env() for i in range(len(result.envs)): e = result.envs[i] if e in names and e.vars(): result.envs[i] = curEnv.freshOld(e) result.envMatches[i] = result.envs[i].isSuperType( parent.envLabels[i], self.world.symList) p = judge.Equality(None) p.nt = False p.lhs = e p.rhs = result.envs[i] vars.append(p.lhs) vars.append(p.rhs) result.premises.append(p) else: names[e] = e for i in range(len(result.args)): a = result.args[i] if a in names and a.vars(): result.args[i] = curEnv.freshOld(a) result.argMatches[i] = result.args[i].isSuperType( parent.argLabels[i], self.world.symList) p = judge.Equality(None) p.nt = False p.lhs = a p.rhs = result.args[i] vars.append(p.lhs) vars.append(p.rhs) result.premises.append(p) else: names[a] = a #store and check the premises for p in ast.children: sp = self.checkPremise(p) if sp: result.premises.append(sp) vars.extend(sp.vars()) #collect together vars bound in the conclusion bound = [] bound.extend( filter(lambda x: util.interestingRoot(x), sum(map(lambda x: x.vars(), result.envs), []))) bound.extend( filter(lambda x: util.interestingRoot(x), sum(map(lambda x: x.vars(), result.args), []))) result.bound = [] result.globals = [] result.freeConc = [] for b in bound: if b not in result.bound: result.bound.append(b) #check if they are bound in the premises if util.interestingRoot( b) and b not in vars and b not in result.freeConc: result.freeConc.append(b) elif self.globalRoot(b) and b not in result.globals: result.globals.append(b) #compute the free vars (variables that are used in the premises, but not the conc) result.free = [] for b in vars: if util.interestingRoot( b) and b not in result.free and b not in result.bound: result.free.append(b) elif self.globalRoot(b) and b not in result.globals: result.globals.append(b) parent.cases.append(result) if result.label in self.world.jCases: self.addErr("Case " + result.label + " already defined", ast) else: self.world.jCases[result.label] = result