def construct_or_on_hyp(proof_step, selected_property: [MathObject], user_input: [str] = None) -> CodeForLean: """ Construct a property 'P or Q' from property 'P' or property 'Q'. Here we assume selected_object contains 1 or 2 items. """ if not user_input: user_input = [] possible_codes = [] first_hypo_name = selected_property[0].info["name"] hypo = selected_property[0].math_type.to_display() if len(selected_property) == 2: if not (selected_property[0].math_type.is_prop() and selected_property[1].math_type.is_prop()): error = _("Selected items are not properties") raise WrongUserInput(error) else: second_selected_property = selected_property[1].info["name"] elif len(selected_property) == 1: if not selected_property[0].math_type.is_prop(): error = _("Selected item is not a property") raise WrongUserInput(error) if not user_input: raise MissingParametersError( InputType.Text, title=_("Obtain 'P OR Q'"), output=_("Enter the proposition you want to use:")) else: second_selected_property = user_input[0] user_input = user_input[1:] if not user_input: raise MissingParametersError( InputType.Choice, [(_("Left"), f'({hypo}) OR ({second_selected_property})'), (_('Right'), f'({second_selected_property}) OR ({hypo})')], title=_("Choose side"), output=_(f'On which side do you want') + f' {hypo} ?') new_hypo_name = get_new_hyp(proof_step) if user_input[0] == 0: possible_codes.append(f'have {new_hypo_name} := ' f'@or.inl _ ({second_selected_property}) ' f'({first_hypo_name})') elif user_input[0] == 1: possible_codes.append(f'have {new_hypo_name} := ' f'@or.inr ({second_selected_property}) _ ' f'({first_hypo_name})') else: raise WrongUserInput("Unexpected error") code = CodeForLean.or_else_from_list(possible_codes) code.add_success_msg( _('Property {} added to the context').format(new_hypo_name)) return code
def action_theorem(proof_step, selected_objects: [MathObject], theorem, target_selected: bool = True ): """ Apply theorem on selected objects or target. """ # test_selection(selected_objects, target_selected) # TODO: For an iff statement, use rewriting # test for iff or equality is removed since it works only with # pkl files goal = proof_step.goal codes = rw_using_statement(goal, selected_objects, theorem) h = get_new_hyp(proof_step) th = theorem.lean_name if len(selected_objects) == 0: codes = codes.or_else(f'apply {th}', success_msg=_('theorem applied to target')) codes = codes.or_else(f'have {h} := @{th}', success_msg=_('theorem added to the context')) else: command = f'have {h} := {th}' command_implicit = f'have {h} := @{th}' names = [item.info['name'] for item in selected_objects] arguments = ' '.join(names) # up to 4 implicit arguments more_codes = [f'apply {th} {arguments}', f'apply @{th} {arguments}'] more_codes += [command + arguments, command_implicit + arguments, command + ' _ ' + arguments, command_implicit + ' _ ' + arguments, command + ' _ _ ' + arguments, command_implicit + ' _ _ ' + arguments, command + ' _ _ _ ' + arguments, command_implicit + ' _ _ _ ' + arguments, command + ' _ _ _ _ ' + arguments, command_implicit + ' _ _ _ _ ' + arguments ] more_codes = CodeForLean.or_else_from_list(more_codes) context_msg = _('theorem') + ' ' + _('applied to') + ' ' + arguments more_codes.add_success_msg(context_msg) codes = codes.or_else(more_codes) codes.add_error_msg(_("unable to apply theorem")) return codes
def action_assumption(proof_step, selected_objects: [MathObject], target_selected: bool = True) -> CodeForLean: """ Translate into string of lean code corresponding to the action. """ goal = proof_step.goal # (1) First trials target = goal.target improved_assumption = solve_target(target) codes = [improved_assumption] # (2) Use user selection if len(selected_objects) == 1: apply_user = CodeForLean.from_string( f'apply {selected_objects[0].info["name"]}') codes.append(apply_user.solve1()) # (3) Conjunctions: try to split hypotheses once # TODO: recursive splitting in hypo # And then retry many things (in improved_assumption_2). split_conj = split_conjunctions_in_context(proof_step) improved_assumption_2 = solve_target(target) # Split target if target.is_and(): # TODO: recursive splitting in target, and_then for each subgoal # apply improved_assumption split_code = CodeForLean.from_string('split, assumption, assumption') improved_assumption_2 = improved_assumption_2.or_else(split_code) # Try norm_num if (goal.target.is_equality() or goal.target.is_inequality() or goal.target.is_false()): # Do not remove above test, since norm_num may solve some # not-so-trivial goal, e.g. implications norm_num_code = CodeForLean.from_string('norm_num at *').solve1() improved_assumption_2 = improved_assumption_2.or_else(norm_num_code) # Try specific properties more_assumptions = search_specific_prop(proof_step) if not more_assumptions.is_empty(): improved_assumption_2 = improved_assumption_2.or_else(more_assumptions) more_code = split_conj.and_then(improved_assumption_2) codes.append(more_code) code = CodeForLean.or_else_from_list(codes) code = code.solve1() code.add_error_msg(_("I don't know how to conclude")) return code
def destruct_iff_on_hyp(proof_step, selected_objects: [MathObject]) -> CodeForLean: """ Split a property 'P iff Q' into two implications. len(selected_objects) should be 1. """ possible_codes = [] hypo_name = selected_objects[0].info["name"] h1 = get_new_hyp(proof_step) h2 = get_new_hyp(proof_step) possible_codes.append(f'cases (iff_def.mp {hypo_name}) with {h1} {h2}') code = CodeForLean.or_else_from_list(possible_codes) code.add_success_msg( _("property {} split into {} and {}").format(hypo_name, h1, h2)) return code
def have_new_property(arrow: MathObject, variable_names: [str], new_hypo_name: str) -> CodeForLean: """ :param arrow: a MathObject which is either an implication or a universal property :param variable_names: a list of names of variables (or properties) to which "arrow" will be applied :param new_hypo_name: a fresh name for the new property return: Lean Code to produce the wanted new property, taking into account implicit parameters """ selected_hypo = arrow.info["name"] command = f'have {new_hypo_name} := {selected_hypo}' command_explicit = f'have {new_hypo_name} := @{selected_hypo}' arguments = ' '.join(variable_names) # try with up to 4 implicit parameters implicit_codes = [ command + ' ' + arguments, command + ' _ ' + arguments, command + ' _ _ ' + arguments, command + ' _ _ _ ' + arguments, command + ' _ _ _ _ ' + arguments ] explicit_codes = [ command_explicit + ' ' + arguments, command_explicit + ' _ ' + arguments, command_explicit + ' _ _ ' + arguments, command_explicit + ' _ _ _ ' + arguments, command_explicit + ' _ _ _ _ ' + arguments ] possible_codes = implicit_codes + explicit_codes code = CodeForLean.or_else_from_list(possible_codes) code.add_success_msg( _("Property {} added to the context").format(new_hypo_name)) return code