Beispiel #1
0
def pop_to_next_proof(cmds):
    lemma_cmd = None
    while len(cmds) > 1:
        cmd = cmds.pop(0)
        if isAdd(cmd) and possiblyStartingProofCmd(getAddBody(cmd)):
            lemma_cmd = cmd
        if isAdd(cmds[0]) and \
           (not isVernacCmd(getAddBody(cmds[0])) or
            re.match("\s*Proof",getAddBody(cmds[0]))):
            return lemma_cmd
    return None
Beispiel #2
0
def build_graph(lemma_cmd, proof_cmds):
    lemma_name = lemma_name_from_statement(getAddBody(lemma_cmd))
    graph = ProofGraph(getAddBody(lemma_cmd))
    next_node_id = 1
    states = [(get_id(lemma_cmd), graph.start_node)]
    state_map = {}
    for cmd in proof_cmds:
        if isAdd(cmd):
            most_recent_state, most_recent_node = states[-1]
            if shouldFilterCommand(cmd):
                state_map[get_id(cmd)] = most_recent_state
                continue
            states.append((get_id(cmd),
                           graph.mkNode(sanitizeTactic(getAddBody(cmd)),
                                        datetime.fromtimestamp(get_time(cmd)),
                                        most_recent_node)))
            next_node_id += 1
            if isFinishingProofCmd(getAddBody(cmd)):
                for statenum, node in states:
                    graph.setNodeColor(node, "blue")
        if isFailed(cmd):
            most_recent_state, most_recent_node = states[-1]
            graph.setNodeColor(most_recent_node, "red")
        if isCancel(cmd):
            cancel_dest = getCancelDest(cmd)
            cancel_dest = state_map.get(cancel_dest, cancel_dest)
            while len(states) > 0 and states[-1][0] != cancel_dest:
                states.pop()
            assert len(states) > 0
    if not os.path.exists("graphs"):
        os.mkdir("graphs")
    graph_filename = "graphs/" + lemma_name + ".svg"
    graph.draw(graph_filename)
    return graph
Beispiel #3
0
def pop_proof(cmds):
    states = []
    proof_cmds = []
    while len(cmds) > 0:
        cmd = cmds.pop(0)
        proof_cmds.append(cmd)
        if isAdd(cmd):
            states.append(get_id(cmd))
            if isEndingProofCmd(getAddBody(cmd)):
                return proof_cmds
        if isCancel(cmd):
            cancel_dest = getCancelDest(cmd)
            while len(states) > 0 and states[-1] != cancel_dest:
                state_num = states.pop()
            if len(states) == 0:
                return proof_cmds
    return proof_cmds
def get_cancel_lengths(cmds):
    states = []
    cancel_lengths = collections.Counter()
    for dat in cmds:
        if isAdd(dat):
            states.append(get_id(dat)-1)
        if isCancel(dat):
            cancel_length = 0
            cancel_dest = getCancelDest(dat)
            if len(states) == 0:
                return collections.Counter()
            while states[-1] != cancel_dest:
                cancel_length += 1
                states.pop()
                if len(states) == 0:
                    return collections.Counter()
            cancel_lengths[cancel_length] += 1
    return cancel_lengths
Beispiel #5
0
def get_stats(proof_cmds):
    all_tactics = collections.Counter()
    cancelled_tactics = collections.Counter()
    failed_tactics = collections.Counter()
    num_tactics = 0
    num_cancellations = 0
    num_failures = 0
    history_stack = []
    for cmd in proof_cmds:
        if isAdd(cmd):
            tactic = getAddBody(cmd)
            history_stack.append((get_id(cmd), tactic))
            if isVernacCmd(tactic):
                continue
            if isGoalPunctuation(tactic):
                continue
            num_tactics += 1
            stem = get_stem(tactic)
            all_tactics[stem] += 1
        if isCancel(cmd):
            cancel_dest = getCancelDest(cmd)
            cancellation_size = 0
            while len(
                    history_stack) > 0 and history_stack[-1][0] != cancel_dest:
                state_num, tactic = history_stack.pop()
                if isVernacCmd(tactic):
                    continue
                if isGoalPunctuation(tactic):
                    continue
                if isFailed(cmd):
                    failed_tactics[get_stem(tactic)] += 1
                cancelled_tactics[get_stem(tactic)] += 1
                cancellation_size += 1
            if isFailed(cmd):
                num_failures += cancellation_size
            num_cancellations += cancellation_size
            assert len(history_stack) > 0

    return ProofMetadata(1, num_tactics, num_cancellations, num_failures,
                         all_tactics, cancelled_tactics, failed_tactics)
def main():
    def addToTacPairCount(table, tac1, tac2):
        if re.match("[-+*\{\}]", tac1) or re.match("[-+*\{\}]", tac2):
            return
        if isVernacCmd(tac1) or isVernacCmd(tac2):
            return
        stem1 = get_stem(tac1)
        stem2 = get_stem(tac2)
        table[(stem1, stem2)] += 1

    def addToTacticCount(table, tactic):
        if re.match("[-+*\{\}]", tactic):
            return
        if isVernacCmd(tactic):
            return
        stem = get_stem(tactic)
        table[stem] += 1

    with open("users.txt", 'r') as usersfile:
        profiles = loads(usersfile.read())

    all_tactics_count = collections.Counter()
    prev_count = collections.Counter()
    failed_prevs_count = collections.Counter()
    next_count = collections.Counter()
    cancelled_replaced_pairs = collections.Counter()
    cancel_lengths = collections.Counter()
    previous_tactic = ''
    just_cancelled = False
    just_failed = False
    total_cancels = 0
    total_failures = 0
    full_matching_cancels = 0
    matching_stem_cancels = 0
    for user in get_users(logdir):
        for session in get_sessions(logdir, user):
            cmds = get_commands(logdir, user, session)
            is_interactive = sublist_contained(cmds, [isCancel, lambda entry: not isCancel(entry)])
            if not is_interactive:
                continue
            preprocessed_cmds = preprocess_vernac_backtrack(
                preprocess_failures(profiles, cmds))
            cancel_lengths += get_cancel_lengths(preprocessed_cmds)

            history = []
            for dat in preprocessed_cmds:
                if isAdd(dat):
                    added_tactic = getAddBody(dat)
                    if not isVernacCmd(added_tactic) and \
                       not isGoalPunctuation(added_tactic):
                        stem = get_stem(added_tactic)
                        assert not isVernacKeyword(stem), added_tactic
                        assert stem.strip() != "", added_tactic
                        all_tactics_count[stem] += 1
                    if just_cancelled:
                        addToTacticCount(next_count, added_tactic)
                        addToTacPairCount(cancelled_replaced_pairs,
                                          previous_tactic, added_tactic)
                        if previous_tactic.strip() == added_tactic.strip():
                            full_matching_cancels += 1
                        try:
                            if get_stem(previous_tactic) == get_stem(added_tactic):
                                matching_stem_cancels += 1
                        except:
                            pass
                        just_cancelled = False
                    previous_tactic = added_tactic
                    history.append((get_id(dat)-1, added_tactic))
                if isCancel(dat):
                    total_cancels += 1
                    just_cancelled = True

                    cancel_dest = getCancelDest(dat)
                    while len(history) > 0 and history[-1][0] != cancel_dest:
                        state_num, tactic = history.pop()
                        addToTacticCount(prev_count, tactic)

                if isFailed(dat):
                    total_failures += 1
                    addToTacticCount(failed_prevs_count, previous_tactic)
    print(cancel_lengths)
    print(f"Of {total_cancels} cancels, {total_failures} were failures ({100 * total_failures / total_cancels:3.2f}%)")
    print(f"Of those cancels, {full_matching_cancels} "
          f"({100 * full_matching_cancels / total_cancels:3.2f}%) "
          f"were replaced with the exact same tactic, "
          f"and {matching_stem_cancels} "
          f"({100 * matching_stem_cancels / total_cancels:3.2f}%) "
          f"were replaced by a tactic with the same stem")
    print("All tactics:")
    for tactic, count in all_tactics_count.most_common(50):
        print(f"{tactic}: {count} occurances")
    print("Tactics before cancel:")
    for tactic, count in prev_count.most_common(25):
        print(f"{tactic}: {count} cancels, {failed_prevs_count[tactic]} failures ({100 * failed_prevs_count[tactic] / count:3.2f}%)")
    print("Tactics after cancel:")
    for tactic, count in next_count.most_common(25):
        print(f"{tactic}: {count} run after cancel")
    print(cancelled_replaced_pairs.most_common(25))