Ejemplo n.º 1
0
def print_app(expr):
    """Takes an application and prints it in the following manner:
    if the application is of the form (..(f a0)... an), print
    f(a0,...,an), or (a0 f a1) if f is infix.
    
    Arguments:
    - `expr`: an expression
    """
    if conf.implicit:
        root, args = root_app_implicit(expr)
        if root.is_const() and root.info.print_iterable_app:
            return print_iterable_app(expr, root)
        elif root.is_const() and root.info.print_implies:
            return print_implies(expr)
        elif root.info.infix and len(args) == 2:
            return "({0!s} {1!s} {2!s})".format(args[0], root, args[1])
        else:
            args_str = map(str, args)
            args_str = ", ".join(args_str)
            return "{0!s}({1!s})".format(root, args_str)
    else:
        root, args = root_app(expr)
        args_str = map(str, args)
        args_str = ", ".join(args_str)
        return "{0!s}({1!s})".format(root, args_str)
Ejemplo n.º 2
0
def print_app(expr):
    """Takes an application and prints it in the following manner:
    if the application is of the form (..(f a0)... an), print
    f(a0,...,an), or (a0 f a1) if f is infix.
    
    Arguments:
    - `expr`: an expression
    """
    if conf.implicit:
        root, args = root_app_implicit(expr)
        if root.is_const() and root.info.print_iterable_app:
            return print_iterable_app(expr, root)
        elif root.is_const() and root.info.print_implies:
            return print_implies(expr)
        elif root.info.infix and len(args) == 2:
            return "({0!s} {1!s} {2!s})".format(args[0], root, args[1])
        else:
            args_str = map(str, args)
            args_str = ", ".join(args_str)
            return "{0!s}({1!s})".format(root, args_str)
    else:
        root, args = root_app(expr)
        args_str = map(str, args)
        args_str = ", ".join(args_str)
        return "{0!s}({1!s})".format(root, args_str)
Ejemplo n.º 3
0
 def __init__(self, inst):
     """
     
     Arguments:
     - `inst`: the name of an instance declaration
     """
     Tactic.__init__(self, 'instance {0!s}'\
                     .format(inst))
     self.inst = inst
     self.root = e.root_app(e.root_clause(inst))[0]
Ejemplo n.º 4
0
 def __init__(self, inst):
     """
     
     Arguments:
     - `inst`: the name of an instance declaration
     """
     Tactic.__init__(self, 'instance {0!s}'\
                     .format(inst))
     self.inst = inst
     self.root = e.root_app(e.root_clause(inst))[0]
Ejemplo n.º 5
0
 def solve(self, goals, context):
     if len(goals) == 0:
         return []
     else:
         prop = goals[0].prop
         root, _ = e.root_app(prop)
         if root.info.is_class and self.root.equals(root):
             return fast_apply(self.inst).solve(goals, context)
         else:
             mess = "Expression {0!s} is not an instance of {1!s}"\
                    .format(root, self.root)
             raise TacticFailure(mess, self, goals)
Ejemplo n.º 6
0
 def solve(self, goals, context):
     if len(goals) == 0:
         return []
     else:
         prop = goals[0].prop
         root, _ = e.root_app(prop)
         if root.info.is_class and self.root.equals(root):
             return fast_apply(self.inst).solve(goals, context)
         else:
             mess = "Expression {0!s} is not an instance of {1!s}"\
                    .format(root, self.root)
             raise TacticFailure(mess, self, goals)
Ejemplo n.º 7
0
 def visit_app(self, expr, model, bindings):
     #evaluate all the arguments at once.
     #Include the implicit arguments.
     f, args = e.root_app(expr)
     f_val = self.visit(f, model, bindings)
     args_val = [self.visit(a, model, bindings) for a in args]
     if (f_val is None):
         if self.strict:
             raise NoValue(expr)
         else:
             return None
     else:
         #call f "strictly" on the arguments
         #this is better performance-wise, but bad for
         #lazy evaluation
         return f_val(*args_val)
Ejemplo n.º 8
0
def definstance(name, ty, expr):
    """
    
    Arguments:
    - `name`: a string
    - `ty`: a type of the form ClassName(t1,...,tn)
    """
    root, _ = root_app(root_clause(ty))
    if root.info.is_class:
        class_name = root.name
        c = defexpr(name, expr, type=ty, unfold=[class_name])
        conf.current_ctxt().class_instances[name] = c.type
        conf.current_ctxt().hyps[name] = c.type
        return c
    else:
        raise Exception("Error in definition of {0!s}:"\
                        "expected {1!s} to be a class name"\
                        .format(name, root))
Ejemplo n.º 9
0
def definstance(name, ty, expr):
    """
    
    Arguments:
    - `name`: a string
    - `ty`: a type of the form ClassName(t1,...,tn)
    """
    root, _ = root_app(root_clause(ty))
    if root.info.is_class:
        class_name = root.name
        c = defexpr(name, expr, type=ty, unfold=[class_name])
        current_ctxt().class_instances[name] = c.type
        current_ctxt().hyps[name] = c.type
        return c
    else:
        raise Exception("Error in definition of {0!s}:"\
                        "expected {1!s} to be a class name"\
                        .format(name, root))
Ejemplo n.º 10
0
def root_app_implicit(expr):
    """If a term is of the form (..(f a0).. an), return the pair
    (f, [ai,..., ak]) where the ai...ak are the non-implicit arguments of f.
    
    Arguments:
    - `expr`: an expression
    """
    r, args = root_app(expr)

    ty, _ = mvar_infer(r, ctxt=conf.current_ctxt())

    non_implicit = []
    i = 0
    while ty.is_pi() and i < len(args):
        if not ty.info.implicit:
            non_implicit.append(args[i])
        i += 1
        ty = ty.body

    return (r, non_implicit)
Ejemplo n.º 11
0
def root_app_implicit(expr):
    """If a term is of the form (..(f a0).. an), return the pair
    (f, [ai,..., ak]) where the ai...ak are the non-implicit arguments of f.
    
    Arguments:
    - `expr`: an expression
    """
    r, args = root_app(expr)

    ty, _ = mvar_infer(r, ctxt=current_ctxt())

    non_implicit = []
    i = 0
    while ty.is_pi() and i < len(args):
        if not ty.info.implicit:
            non_implicit.append(args[i])
        i += 1
        ty = ty.body

    return (r, non_implicit)
Ejemplo n.º 12
0
 def solve(self, goals, context):
     if len(goals) == 0:
         return []
     else:
         hyps = goals[0].tele.types
         hyp_insts = [i for i in hyps if e.root_app(i)[0].info.is_class]
         ctxt_insts = context.to_list_rec('class_instances')
         for inst in hyp_insts + ctxt_insts:
             try:
                 mvar_stack.new()
                 return now(sub_mvar\
                            >> instance(inst)\
                            >> unify\
                            >> par(trytac(self))\
                            >> unify)\
                        .solve(goals, context)
             except TacticFailure:
                 mvar_stack.free()
         goal_str = goals[0].prop
         mess = "No class instances for goal {0!s}".format(goal_str)
         raise TacticFailure(mess, self, goals)
Ejemplo n.º 13
0
 def solve(self, goals, context):
     if len(goals) == 0:
         return []
     else:
         hyps = goals[0].tele.types
         hyp_insts = [i for i in hyps if e.root_app(i)[0].info.is_class]
         ctxt_insts = context.to_list_rec('class_instances')
         for inst in hyp_insts + ctxt_insts:
             try:
                 mvar_stack.new()
                 return now(sub_mvar\
                            >> instance(inst)\
                            >> unify\
                            >> par(trytac(self))\
                            >> unify)\
                        .solve(goals, context)
             except TacticFailure:
                 mvar_stack.free()
         goal_str = goals[0].prop
         mess = "No class instances for goal {0!s}".format(goal_str)
         raise TacticFailure(mess, self, goals)
Ejemplo n.º 14
0
def solve_ineqs(goals):
    """Solve a goal set consisting of subtyping constraints,
    possibly containing meta-variables.
    
    Arguments:
    - `goals`: a goal set
    """
    goals.solve_with(
        trivial >> repeat(destruct >> trivial) >> par(trytac(sub_tac)))
    if goals.is_solved():
        return goals
    else:
        ineqs = goals.goals
        c = ineqs[0].prop
        assert (c.is_sub())
        #destruct>>trivial was unable to solve the constraint
        if not (c.lhs.is_mvar() or c.rhs.is_mvar()):
            #in this case, we have a higher-order unification problem, and
            #we just give up in hopes of finding an instance later (e.g. using
            #a type class)
            if e.root_app(c.lhs)[0].is_mvar() or \
                   e.root_app(c.rhs)[0].is_mvar():
                return goals
            else:
                raise UnsolvabeConstr(c)
        else:
            if c.lhs.is_mvar():
                m = c.lhs
            else:
                m = c.rhs
            assert (m.is_mvar())

            lt, gt, other = split(m, ineqs)

            if len(lt) == 1 and len(gt) == 0:
                m.set_val(lt[0].prop.lhs)
                m_elim = other
            elif len(lt) == 0 and len(gt) == 1:
                m.set_val(gt[0].prop.rhs)
                mvar_stack.push(m)
                m_elim = other
            elif len(lt) == 1 and len(gt) == 1 and \
                     (lt[0].prop.lhs is gt[0].prop.rhs):
                m.set_val(lt[0].prop.lhs)
                mvar_stack.push(m)
                m_elim = other
            else:
                m_elim = cross(lt, gt) + other

            elim_goals = Goals('solve_ineqs', goals.context, goals=m_elim)
            solve_ineqs(elim_goals)

            lt = map(sub_in_goal, lt)
            gt = map(sub_in_goal, gt)

            if len(lt) != 0:
                lbs = [ineq.prop.lhs for ineq in lt]
                glb = max_type(lbs, goals.context)
                if not (glb is None):
                    m.set_val(glb)
                    mvar_stack.push(m)
                else:
                    #Try the first possible solution
                    m.set_val(lbs[0])
                    mvar_stack.push(m)
            elif len(gt) != 0:
                ubs = [ineq.prop.rhs for ineq in gt]
                lub = min_type(ubs, goals.context)
                if not (lub is None):
                    m.set_val(lub)
                    mvar_stack.push(m)
                else:
                    #Try the first possible solution
                    m.set_val(ubs[0])
                    mvar_stack.push(m)
            else:
                assert (False)
        goals.solve_with(sub_mvar >> trivial)
        if goals.is_solved():
            return goals
        else:
            return solve_ineqs(goals)
Ejemplo n.º 15
0
def solve_ineqs(goals):
    """Solve a goal set consisting of subtyping constraints,
    possibly containing meta-variables.
    
    Arguments:
    - `goals`: a goal set
    """
    goals.solve_with(trivial >>
                          repeat(destruct >> trivial)
                          >> par(trytac(sub_tac)))
    if goals.is_solved():
        return goals
    else:
        ineqs = goals.goals
        c = ineqs[0].prop
        assert(c.is_sub())
        #destruct>>trivial was unable to solve the constraint
        if not (c.lhs.is_mvar() or c.rhs.is_mvar()):
            #in this case, we have a higher-order unification problem, and
            #we just give up in hopes of finding an instance later (e.g. using
            #a type class)
            if e.root_app(c.lhs)[0].is_mvar() or \
                   e.root_app(c.rhs)[0].is_mvar():
                return goals
            else:
                raise UnsolvabeConstr(c)
        else:
            if c.lhs.is_mvar():
                m = c.lhs
            else:
                m = c.rhs
            assert(m.is_mvar())

            lt, gt, other = split(m, ineqs)

            if len(lt) == 1 and len(gt) == 0:
                m.set_val(lt[0].prop.lhs)
                m_elim = other
            elif len(lt) == 0 and len(gt) == 1:
                m.set_val(gt[0].prop.rhs)
                mvar_stack.push(m)
                m_elim = other
            elif len(lt) == 1 and len(gt) == 1 and \
                     (lt[0].prop.lhs is gt[0].prop.rhs):
                m.set_val(lt[0].prop.lhs)
                mvar_stack.push(m)
                m_elim = other
            else:
                m_elim = cross(lt, gt) + other

            elim_goals = Goals('solve_ineqs', goals.context, goals=m_elim)
            solve_ineqs(elim_goals)

            lt = map(sub_in_goal, lt)
            gt = map(sub_in_goal, gt)

            if len(lt) != 0:
                lbs = [ineq.prop.lhs for ineq in lt]
                glb = max_type(lbs, goals.context)
                if not (glb is None):
                    m.set_val(glb)
                    mvar_stack.push(m)
                else:
                    #Try the first possible solution
                    m.set_val(lbs[0])
                    mvar_stack.push(m)
            elif len(gt) != 0:
                ubs = [ineq.prop.rhs for ineq in gt]
                lub = min_type(ubs, goals.context)
                if not (lub is None):
                    m.set_val(lub)
                    mvar_stack.push(m)
                else:
                    #Try the first possible solution
                    m.set_val(ubs[0])
                    mvar_stack.push(m)
            else:
                assert(False)
        goals.solve_with(sub_mvar >> trivial)
        if goals.is_solved():
            return goals
        else:
            return solve_ineqs(goals)