Exemplo n.º 1
0
def apply_substitute(proof_step, l: [MathObject], user_input: [int], equality):
    """
    Try to rewrite the goal or the first selected property using the last
    selected property.
    """

    goal = proof_step.goal

    codes = CodeForLean.empty_code()
    heq = l[-1]
    left_term = equality.children[0]
    right_term = equality.children[1]
    success1 = ' ' + _("{} replaced by {}").format(left_term.to_display(),
                                             right_term.to_display()) + ' '
    success2 = ' ' + _("{} replaced by {}").format(right_term.to_display(),
                                             left_term.to_display()) + ' '
    choices = [(left_term.to_display(),
                f'Replace by {right_term.to_display()}'),
               (right_term.to_display(),
                f'Replace by {left_term.to_display()}')]
            
    if len(l) == 1:
        # If the user has chosen a direction, apply substitution
        # else if both directions make sense, ask the user for a choice
        # else try direct way or else reverse way.
        h = l[0].info["name"]
        if len(user_input) > 0:
            if user_input[0] == 1:
                success_msg = success2 + _("in target")
                more_code = CodeForLean.from_string(f'rw <- {h}',
                                                    success_msg=success_msg)
            elif user_input[0] == 0:
                success_msg = success1 + _("in target")
                more_code = CodeForLean.from_string(f'rw {h}',
                                                    success_msg=success_msg)
            codes = codes.or_else(more_code)
        else:
            if goal.target.math_type.contains(left_term) and \
                    goal.target.math_type.contains(right_term):
                
                raise MissingParametersError(
                    InputType.Choice,
                    choices, 
                    title=_("Precision of substitution"),
                    output=_("Choose which expression you want to replace"))
            else:
                msg2 = success2 + _("in target")
                more_code2 = CodeForLean.from_string(f'rw <- {h}',
                                                     success_msg=msg2)
                codes = codes.or_else(more_code2)
                msg1 = success1 + _("in target")
                more_code1 = CodeForLean.from_string(f'rw {h}',
                                                     success_msg=msg1)
                codes = codes.or_else(more_code1)

    if len(l) == 2:
        h = l[0].info["name"]
        heq_name = l[-1].info["name"]
        if len(user_input) > 0:
            if user_input[0] == 1:
                success_msg = success2 + _("in {}").format(h)
                more_code = CodeForLean.from_string(f'rw <- {heq_name} at {h}',
                                                    success_msg=success_msg)
                codes = codes.or_else(more_code)

            elif user_input[0] == 0:
                success_msg = success1 + _("in {}").format(h)
                more_code = CodeForLean.from_string(f'rw {heq_name} at {h}',
                                                    success_msg=success_msg)
                codes = codes.or_else(more_code)
        else:
            if l[0].math_type.contains(left_term) and \
                    l[0].math_type.contains(right_term):
                    
                raise MissingParametersError(
                    InputType.Choice,
                    choices, 
                    title=_("Precision of substitution"),
                    output=_("Choose which expression you want to replace"))

        # h, heq_name = heq_name, h
        # codes = codes.or_else(f'rw <- {heq_name} at {h}')
        # codes = codes.or_else(f'rw {heq_name} at {h}')

        msg2 = success2 + _("in {}").format(h)
        more_code2 = CodeForLean.from_string(f'rw <- {heq_name} at {h}',
                                             success_msg=msg2)
        codes = codes.or_else(more_code2)
        msg1 = success1 + _("in {}").format(h)
        more_code1 = CodeForLean.from_string(f'rw {heq_name} at {h}',
                                             success_msg=msg1)
        codes = codes.or_else(more_code1)

    if heq.is_for_all():
        # if property is, e.g. "∀n, u n = c"
        # there is a risk of meta vars if Lean does not know to which n
        # applying the equality
        codes = codes.and_then('no_meta_vars')
    return codes
Exemplo n.º 2
0
def action_new_object(proof_step,
                      selected_objects: [MathObject],
                      user_input: [str] = None,
                      target_selected: bool = True) -> CodeForLean:
    """
    Introduce new object / sub-goal / function
    """

    goal = proof_step.goal

    codes = []
    # Choose between object/sub-goal/function
    if not user_input:
        raise MissingParametersError(InputType.Choice,
                             [(_("Object"), _("Introduce a new object")),
                              (_("Goal"), _("Introduce a new "
                                            "intermediate sub-goal")),
                              (_("Function"), _("Introduce a new "
                                                "function"))],
                             title=_("New object"),
                             output=_("Choose what to introduce:"))
    # Choice = new object
    if user_input[0] == 0:
        if len(user_input) == 1:  # Ask for name
            raise MissingParametersError(InputType.Text,
                                         title="+",
                                         output=_("Name your object:"))
        if len(user_input) == 2:  # Ask for new object
            raise MissingParametersError(InputType.Text,
                                         title="+",
                                         output=_("Introduce a new object")
                                         + "(" + _("e.g.")
                                         + "0, {1}, f(2), ...)")
        else:  # Send code
            name = user_input[1]
            new_hypo_name = get_new_hyp(proof_step)
            new_object = user_input[2]
            codes = CodeForLean.from_string(f"let {name} := {new_object}")
            codes = codes.and_then(f"have {new_hypo_name} : {name} = "
                                                     f"{new_object}")
            codes = codes.and_then("refl")
            codes.add_success_msg(_("New object {} added to the context").
                                  format(name))
            if goal.target.is_for_all():
                # User might want to prove a universal property "∀x..."
                # and mistake "new object" for introduction of the relevant x.
                codes.add_error_msg(_("You might try the ∀ button..."))

    # Choice = new sub-goal
    elif user_input[0] == 1:
        if len(user_input) == 1:
            raise MissingParametersError(InputType.Text,
                                         title="+",
                                         output=_("Introduce new subgoal:"))
        else:
            new_hypo_name = get_new_hyp(proof_step)
            codes = CodeForLean.from_string(f"have {new_hypo_name}:"
                                                     f" ({user_input[1]})")
            codes.add_success_msg(_("New target will be added to the context "
                                    "after being proved"))
            codes.add_subgoal(user_input[1])
    # Choice = new function
    elif user_input[0] == 2:
        return introduce_fun(proof_step, selected_objects)
    return codes