Skip to content

Commit 35ebaaa

Browse files
authored
(incomplete) handling of aborted proofs (#56)
1 parent 17a16bc commit 35ebaaa

File tree

4 files changed

+66
-42
lines changed

4 files changed

+66
-42
lines changed

coqpyt/coq/context.py

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,10 +489,61 @@ def term_type(self, step: Step) -> TermType:
489489
step (Step): The step to be processed.
490490
491491
Returns:
492-
List: The term type of the step.
492+
TermType: The term type of the step.
493493
"""
494494
return self.__term_type(self.expr(step))
495495

496+
def is_proof_term(self, step: Step) -> bool:
497+
"""
498+
Args:
499+
step (Step): The step to be processed.
500+
501+
Returns:
502+
bool: Whether the step introduces a new proof term.
503+
"""
504+
term_type = self.term_type(step)
505+
# Assume that terms of the following types do not introduce new proofs
506+
# FIXME: Should probably check if goals were changed
507+
return term_type not in [
508+
TermType.TACTIC,
509+
TermType.NOTATION,
510+
TermType.INDUCTIVE,
511+
TermType.COINDUCTIVE,
512+
TermType.RECORD,
513+
TermType.CLASS,
514+
TermType.SCHEME,
515+
TermType.VARIANT,
516+
TermType.OTHER,
517+
]
518+
519+
def is_end_proof(self, step: Step) -> bool:
520+
"""
521+
Args:
522+
step (Step): The step to be processed.
523+
524+
Returns:
525+
bool: Whether the step closes an open proof term.
526+
"""
527+
# FIXME: Refer to issue #55: https://github.com/sr-lab/coqpyt/issues/55
528+
expr = self.expr(step)[0]
529+
return expr in ["VernacEndProof", "VernacExactProof", "VernacAbort"]
530+
531+
def is_segment_delimiter(self, step: Step) -> bool:
532+
"""
533+
Args:
534+
step (Step): The step to be processed.
535+
536+
Returns:
537+
bool: Whether the step delimits a segment (module or section).
538+
"""
539+
expr = self.expr(step)[0]
540+
return expr in [
541+
"VernacEndSegment",
542+
"VernacDefineModule",
543+
"VernacDeclareModuleType",
544+
"VernacBeginSection",
545+
]
546+
496547
def update(self, context: Union["FileContext", Dict[str, Term]] = {}):
497548
"""Updates the context with new terms.
498549

coqpyt/coq/proof_file.py

Lines changed: 9 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -533,48 +533,21 @@ def __handle_proof_term(
533533
index, ProofTerm(proof_term, statement_context, [], program)
534534
)
535535

536-
def __is_proof_term(self, step: Step):
537-
term_type = self.context.term_type(step)
538-
# Assume that terms of the following types do not introduce new proofs
539-
# FIXME: Should probably check if goals were changed
540-
return term_type not in [
541-
TermType.TACTIC,
542-
TermType.NOTATION,
543-
TermType.INDUCTIVE,
544-
TermType.COINDUCTIVE,
545-
TermType.RECORD,
546-
TermType.CLASS,
547-
TermType.SCHEME,
548-
TermType.VARIANT,
549-
TermType.OTHER,
550-
]
551-
552-
def __is_end_proof(self, step: Step):
553-
return self.context.expr(step)[0] in ["VernacEndProof", "VernacExactProof"]
554-
555536
def __check_proof_step(self, step: Step, undo: bool = False):
556537
# Avoids Tactics, Notations, Inductive...
557538
if self.context.term_type(step) == TermType.OTHER:
558539
self.__handle_proof_step(step, undo=undo)
559-
elif self.__is_proof_term(step):
540+
elif self.context.is_proof_term(step):
560541
self.__handle_proof_term(step, undo=undo)
561542

562-
def __is_segment_delimiter(self, step: Step):
563-
return self.context.expr(step)[0] in [
564-
"VernacEndSegment",
565-
"VernacDefineModule",
566-
"VernacDeclareModuleType",
567-
"VernacBeginSection",
568-
]
569-
570543
def __step(self, step: Step, undo: bool):
571544
file_change = self.__aux_file.truncate if undo else self.__aux_file.append
572545
file_change(step.text)
573546
# Ignore segment delimiters because it affects Program handling
574-
if self.__is_segment_delimiter(step):
547+
if self.context.is_segment_delimiter(step):
575548
return
576549
# Found [Qed]/[Defined]/[Admitted] or [Proof <exact>.]
577-
if self.__is_end_proof(step):
550+
if self.context.is_end_proof(step):
578551
self.__handle_end_proof(step, undo=undo)
579552
# New obligations were introduced
580553
elif self.__has_obligations(step):
@@ -685,12 +658,12 @@ def __local_exec(self, n_steps=1):
685658
def __add_step(self, index: int):
686659
step = self.steps[index]
687660
# Ignore segment delimiters because it affects Program handling
688-
if self.__is_segment_delimiter(step):
661+
if self.context.is_segment_delimiter(step):
689662
pass
690663

691664
optional = self.__find_step(self.steps[index - 1].ast.range)
692665
# Handles case where Qed is added
693-
if self.__is_end_proof(step):
666+
if self.context.is_end_proof(step):
694667
# This is not outside of the ifs for performance reasons
695668
goals = self.__goals(step.ast.range.end)
696669
index = self.__find_proof_index(step)
@@ -700,7 +673,7 @@ def __add_step(self, index: int):
700673
elif self.__has_obligations(step):
701674
self.__handle_obligations(step)
702675
# Allows to add open proofs
703-
elif self.__is_proof_term(step):
676+
elif self.context.is_proof_term(step):
704677
# This is not outside of the ifs for performance reasons
705678
goals = self.__goals(step.ast.range.end)
706679
if self.__in_proof(goals):
@@ -722,12 +695,12 @@ def __add_step(self, index: int):
722695

723696
def __delete_step(self, step: Step):
724697
# Ignore segment delimiters because it affects Program handling
725-
if self.__is_segment_delimiter(step):
698+
if self.context.is_segment_delimiter(step):
726699
return
727700

728701
optional = self.__find_step(step.ast.range)
729702
# Handles case where Qed is deleted
730-
if self.__is_end_proof(step):
703+
if self.context.is_end_proof(step):
731704
index = self.__find_proof_index(step) - 1
732705
open_index = self.__find_open_proof_index(step)
733706
self.__handle_end_proof(step, index=index, open_index=open_index, undo=True)
@@ -816,7 +789,7 @@ def __is_proven(self, proof: ProofTerm) -> bool:
816789
if len(proof.steps) == 0:
817790
return False
818791
return (
819-
self.__is_end_proof(proof.steps[-1].step)
792+
self.context.is_end_proof(proof.steps[-1].step)
820793
and "Admitted" not in proof.steps[-1].step.short_text
821794
)
822795

coqpyt/tests/proof_file/expected/valid_file.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ proofs:
185185
end:
186186
line: 25
187187
character: 16
188-
- text: "\n Defined."
188+
- text: "\n Abort."
189189
goals:
190190
position:
191191
line: 26
@@ -196,7 +196,7 @@ proofs:
196196
character: 2
197197
end:
198198
line: 26
199-
character: 10
199+
character: 8
200200
context:
201201
- "8.19.x":
202202
text: "Notation \"∀ x .. y , P\" := (forall x, .. (forall y, P) ..) (at level 10, x binder, y binder, P at level 200, format \"'[ ' '[ ' ∀ x .. y ']' , '/' P ']'\") : type_scope."
@@ -275,7 +275,7 @@ proofs:
275275
context:
276276
- text: "Ltac reduce_eq := simpl; reflexivity."
277277
type: TACTIC
278-
- text: "\n Qed."
278+
- text: "\n Defined."
279279
goals:
280280
position:
281281
line: 38

coqpyt/tests/resources/test_valid.v

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Section Random.
2424
rewrite -> (plus_O_n (S n * m)).
2525
Compute True /\ True.
2626
reflexivity.
27-
Defined.
27+
Abort.
2828
End Random.
2929

3030
Module Extra.
@@ -36,7 +36,7 @@ Module Extra.
3636
Compute mk_example n n.
3737
Compute Out.In.plus_O_n.
3838
reduce_eq.
39-
Qed.
39+
Defined.
4040
End Fst.
4141

4242
Module Snd.

0 commit comments

Comments
 (0)