예제 #1
0
 def run_to_next_vernac(coq: serapi_instance.SerapiInstance, pbar: tqdm,
                        initial_full_context: FullContext,
                        lemma_statement: str) -> List[TacticInteraction]:
     nonlocal commands_run
     nonlocal commands_in
     coq.run_stmt(lemma_statement)
     original_tactics: List[TacticInteraction] = []
     lemma_name = serapi_instance.lemma_name_from_statement(lemma_statement)
     try:
         while coq.full_context != None:
             next_in_command = commands_in.pop(0)
             context_before = coq.fullContext
             original_tactics.append(
                 TacticInteraction(next_in_command, context_before))
             coq.run_stmt(next_in_command)
             pbar.update(1)
         body_tactics = [t.tactic for t in original_tactics]
         if next_in_command.strip() == "Defined.":
             append_to_solution_vfile(
                 args.output_dir, args.filename,
                 [f"Reset {lemma_name}.", lemma_statement] + body_tactics)
         commands_run.append(lemma_statement)
         commands_run += body_tactics
     except:
         commands_in = [lemma_statement] + \
             [t.tactic for t in original_tactics] \
             + commands_in
         raise
     return original_tactics
예제 #2
0
 def write_lemma_button(lemma_statement: str, region_idx: int):
     nonlocal tag
     nonlocal text
     lemma_name = \
         serapi_instance.lemma_name_from_statement(lemma_statement)
     with tag('button', klass='collapsible',
              id=f'collapsible-{region_idx}'):
         with tag('code', klass='buttontext'):
             write_highlighted(lemma_statement.strip())
예제 #3
0
def write_lemma_button(lemma_statement: str, module: Optional[str],
                       status_klass: str, tag: Tag, text: Text):
    global obligation_number
    lemma_name = \
        serapi_instance.lemma_name_from_statement(lemma_statement)
    module_prefix = f"{module}Zd" if module else ""
    if lemma_name == "Obligation":
        obligation_number += 1
        fullname = module_prefix + lemma_name + str(obligation_number)
    else:
        fullname = module_prefix + lemma_name
    with tag('button',
             klass='collapsible {}'.format(status_klass),
             onmouseover="hoverLemma(\"{}\")".format(fullname),
             onmouseout="unhoverLemma(\"{}\")".format(fullname)):
        with tag('code', klass='buttontext'):
            text(lemma_statement.strip())
예제 #4
0
def count_proofs(args : argparse.Namespace, filename : str) \
    -> Tuple[int, int]:
    eprint(f"Counting {filename}", guard=args.debug)
    scrapefile = args.prelude + "/" + filename + ".scrape"
    interactions = list(
        read_all_text_data(args.prelude + "/" + filename + ".scrape"))
    filter_func = get_context_filter(args.context_filter)

    count = 0
    total_count = 0
    cur_proof_counts = False
    cur_lemma_stmt = ""
    extended_interactions : List[Optional[ScrapedCommand]] = \
        cast(List[Optional[ScrapedCommand]], interactions[1:])  + [None]
    for inter, next_inter in zip(interactions, extended_interactions):
        if isinstance(inter, ScrapedTactic):
            goal_before = inter.goal
            hyps_before = inter.hypotheses
            command = inter.tactic
        else:
            goal_before = ""
            hyps_before = []
            command = inter

        if next_inter and isinstance(next_inter, ScrapedTactic):
            goal_after = next_inter.goal
            hyps_after = next_inter.hypotheses
        else:
            goal_after = ""
            hyps_after = []

        entering_proof = bool((not goal_before) and goal_after)
        exiting_proof = bool(goal_before and not goal_after)

        if entering_proof:
            cur_lemma_stmt = next_inter.prev_tactics[0]
            cur_proof_counts = False if args.some else True
            continue

        if cur_lemma_stmt:
            if filter_func(
                {
                    "goal": format_goal(goal_before),
                    "hyps": hyps_before
                }, command, {
                    "goal": format_goal(goal_after),
                    "hyps": goal_after
                }, args):
                if args.some and not cur_proof_counts:
                    cur_proof_counts = True
            else:
                if args.all and cur_proof_counts:
                    cur_lemma_name = serapi_instance.lemma_name_from_statement(
                        cur_lemma_stmt)
                    eprint(
                        f"Eliminating proof {cur_lemma_name} "
                        f"because tactic {command.strip()} doesn't match",
                        guard=args.debug)
                    cur_proof_counts = False

        if exiting_proof:
            if cur_proof_counts:
                cur_lemma_name = serapi_instance.lemma_name_from_statement(
                    cur_lemma_stmt)
                if args.print_name:
                    print(cur_lemma_name)
                if args.print_stmt:
                    print(re.sub("\n", "\\n", cur_lemma_stmt))
                eprint(f"Proof of {cur_lemma_name} counts", guard=args.debug)
                count += 1
            total_count += 1
            cur_lemma_stmt = ""
    if not args.print_name and not args.print_stmt:
        print(f"{filename}: {count}/{total_count} "
              f"({stringified_percent(count, total_count)}%)")
    return count, total_count
예제 #5
0
def dfs_proof_search_with_graph(lemma_statement : str,
                                module_name : Optional[str],
                                coq : serapi_instance.SerapiInstance,
                                args : argparse.Namespace,
                                bar_idx : int) \
                                -> SearchResult:
    global obligation_number
    lemma_name = serapi_instance.lemma_name_from_statement(lemma_statement)
    g = SearchGraph(lemma_name)

    def cleanupSearch(num_stmts: int, msg: Optional[str] = None):
        if msg:
            eprint(f"Cancelling {num_stmts} statements "
                   f"because {msg}.",
                   guard=args.debug)
        for _ in range(num_stmts):
            coq.cancel_last()

    hasUnexploredNode = False

    def search(pbar: tqdm, current_path: List[LabeledNode],
               subgoal_distance_stack: List[int],
               extra_depth: int) -> SubSearchResult:
        nonlocal hasUnexploredNode
        # print(coq.use_hammer)
        if coq.use_hammer:
            predictionNodes = makeHammerPredictions(g, coq, current_path[-1],
                                                    args.search_width)
        else:
            predictionNodes = makePredictions(g, coq, current_path[-1],
                                              args.search_width)
        for predictionNode in predictionNodes:
            try:
                context_after, num_stmts, subgoals_closed, subgoals_opened = \
                    tryPrediction(args, coq, g, predictionNode)
                pbar.update(1)

                #### 1.
                if subgoal_distance_stack:
                    new_distance_stack = (subgoal_distance_stack[:-1] +
                                          [subgoal_distance_stack[-1] + 1])
                else:
                    new_distance_stack = []

                #### 2.
                new_extra_depth = extra_depth
                for _ in range(subgoals_closed):
                    closed_goal_distance = new_distance_stack.pop()
                    new_extra_depth += closed_goal_distance

                #### 3.
                new_distance_stack += [0] * subgoals_opened
                # if subgoals_opened > 0:
                #     eprint(f"Opened {subgoals_opened} subgoals with "
                #            f"{predictionNode.prediction}")

                #### 4.

                #############
                if completed_proof(coq):
                    solution = g.mkQED(predictionNode)
                    return SubSearchResult(solution, subgoals_closed)
                elif contextInPath(context_after,
                                   current_path[1:] + [predictionNode]):
                    g.setNodeColor(predictionNode, "orange")
                    nodes_skipped = numNodesInTree(
                        args.search_width,
                        (args.search_depth + 1) - len(current_path)) - 1
                    pbar.update(nodes_skipped)
                    cleanupSearch(num_stmts,
                                  "resulting context is in current path")
                elif len(current_path) < args.search_depth + new_extra_depth:
                    sub_search_result = search(pbar,
                                               current_path + [predictionNode],
                                               new_distance_stack,
                                               new_extra_depth)
                    cleanupSearch(num_stmts, "we finished subsearch")
                    if sub_search_result.solution or \
                       sub_search_result.solved_subgoals > subgoals_opened:
                        new_subgoals_closed = \
                            subgoals_closed + \
                            sub_search_result.solved_subgoals - \
                            subgoals_opened
                        return SubSearchResult(sub_search_result.solution,
                                               new_subgoals_closed)
                    if subgoals_closed > 0:
                        return SubSearchResult(None, subgoals_closed)
                else:
                    hasUnexploredNode = True
                    cleanupSearch(num_stmts, "we hit the depth limit")
                    if subgoals_closed > 0:
                        return SubSearchResult(None, subgoals_closed)
            except (serapi_instance.CoqExn, serapi_instance.TimeoutError,
                    serapi_instance.OverflowError, serapi_instance.ParseError,
                    serapi_instance.UnrecognizedError):
                g.setNodeColor(predictionNode, "red")
                nodes_skipped = numNodesInTree(
                    args.search_width,
                    (args.search_depth + 1) - len(current_path)) - 1
                pbar.update(nodes_skipped)
                continue
            except serapi_instance.NoSuchGoalError:
                raise
        return SubSearchResult(None, 0)

    total_nodes = numNodesInTree(args.search_width, args.search_depth + 2) - 1
    with tqdm(total=total_nodes,
              unit="pred",
              file=sys.stdout,
              desc="Proof",
              disable=(not args.progress),
              leave=False,
              position=((bar_idx * 2) + 1),
              dynamic_ncols=True,
              bar_format=mybarfmt) as pbar:
        command_list, _ = search(pbar, [g.start_node], [], 0)
        pbar.clear()
    module_prefix = f"{module_name}Zd" if module_name else ""
    if lemma_name == "Obligation":
        obligation_number += 1
        g.draw(
            f"{args.output_dir}/{module_prefix}{lemma_name}{obligation_number}.svg"
        )
    else:
        g.draw(f"{args.output_dir}/{module_prefix}{lemma_name}.svg")
    if command_list:
        return SearchResult(SearchStatus.SUCCESS, command_list)
    elif hasUnexploredNode:
        return SearchResult(SearchStatus.INCOMPLETE, None)
    else:
        return SearchResult(SearchStatus.FAILURE, None)