예제 #1
0
 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)
예제 #2
0
파일: env.py 프로젝트: nrc/N
 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()
예제 #3
0
파일: env.py 프로젝트: nrc/N
 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()
예제 #4
0
파일: env.py 프로젝트: nrc/N
 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
예제 #5
0
파일: env.py 프로젝트: nrc/N
    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
예제 #6
0
  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
예제 #7
0
파일: nchecker.py 프로젝트: nrc/N
  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
예제 #8
0
파일: nchecker.py 프로젝트: nrc/N
    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