Proof automation¶
Harpoon provides rudimentary automation for basic tasks during proofs.
Each automation type can be controlled via the toggle-automation
tactic.
Automations run at the moment that a new subgoal is created.
Actions performed by automatic tactics can be undone.
auto-intros
¶
This automation introduces assumptions into the context whenever the subgoal has a function type.
auto-solve-trivial
¶
This automation solves subgoals in which the context contains an assumption whose type is convertible with goal type.
It will never solve the last remaining subgoal in a theorem, as this makes
certain theorems impossible to prove using Harpoon. For example, this is
essential for implementing a function such as double : [|- nat] -> [|- nat]
:
auto-intros
will bring x : [|- nat]
into the context and
auto-solve-trivial
would immediately finish the theorem before the user ever
sees a subgoal prompt.
actions capabilities.
- Current limitations:
- no paramater variables
- no substitution variables
- no case splits (>1 case produced)
- no pair type
- no splitting on contexts
auto-invert-solve
¶
This automation attempts to solve the subgoal if no variable splitting (other than inversions) is required to solve
the goal. It performs 2 iterations of depth-first proof-search, once on the computation level, and
once again on the LF level. Use auto-invert-solve INT
to specify the maximum depth
you want your search tree to reach. Depth is incremented when we attempt to
solve a subgoal.
For example, if we want to solve Ev [|- S (S (S (S z)))]
this would require
a depth bound of at least 2::
inductive Ev : [⊢ nat] → ctype =
| ZEv : Ev [⊢ z]
| SEv : Ev [⊢ N] → Ev [⊢ S (S N)]
depth = 0
solve for Ev [|- S (S (S (S z)))] -> focus on SEv --->
depth = 1
solve for Ev [|- S (S z)] -> focus on SEv --->
depth = 2
solve for Ev [|- z] -> focus on zEv
Note: If a goal has more than one subgoal, depth only increments by 1.
For example, if we want to solve ``Less_Than [|- S z] [|- S (S (S z))]`` this
would require depth bound of 3:
inductive Less_Than : [⊢ nat] → [⊢ nat] → ctype =
| ZLT : Less_Than [⊢ z] [⊢ S N]
| LT : Less_Than [⊢ N] [⊢ M] → Less_Than [⊢ S N] [⊢ S M]
| Trans_LT : Less_Than [⊢ N] [⊢ M]
→ Less_Than [⊢ M] [⊢ K] → Less_Than [⊢ N] [⊢ K]
depth = 0
solve for Less_Than [|- S z] [|- S (S (S z))] -> focus on Trans_LT --->
depth = 1
solve for Less_Than [|- M] [|- S (S (S z))] -> focus on LT --->
depth = 2
solve for Less_Than [|- M'] [|- S (S z)] -> focus on LT --->
depth = 3
solve for Less_Than [|- M''] [|- S z] -> focus on ZLT
---> found LT LT ZLT : Less_Than [|- S (S z)] [|- S (S (S z))]
depth = 1
solve for Less_Than [|- S z] [|- S (S z)] -> focus on LT --->
depth = 2
solve for Less_Than [|- z] [|- S z] -> focus on ZLT
---> found LT ZLT : Less_Than [|- S z] [|- S (S z)]
-> found Trans_LT (LT ZLT) (LT LT ZLT) : Less_Than [|- S z] [|- S (S (S z))]
inductive-auto-solve
¶
This automation will perform a case split on the user-specified variable then call auto-invert-solve on each sub case. Use inductive-auto-solve INT
to specify the maximum depth you want your search tree to reach. Depth is incremented as above.