forked from impermeable/waterproof
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: first version of waterproof specialize tactic * feat: Improve new specialize tactic, so it throws an error when a wrong variable is getting introduced. * Avoid doubling hypothesis, allow for multiple binders, prevent matching on functions, rename hypothesis to user-specified one --------- Co-authored-by: Jelle <[email protected]>
- Loading branch information
1 parent
5795562
commit efa0e41
Showing
7 changed files
with
303 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
(******************************************************************************) | ||
(* This file is part of Waterproof-lib. *) | ||
(* *) | ||
(* Waterproof-lib is free software: you can redistribute it and/or modify *) | ||
(* it under the terms of the GNU General Public License as published by *) | ||
(* the Free Software Foundation, either version 3 of the License, or *) | ||
(* (at your option) any later version. *) | ||
(* *) | ||
(* Waterproof-lib is distributed in the hope that it will be useful, *) | ||
(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) | ||
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) | ||
(* GNU General Public License for more details. *) | ||
(* *) | ||
(* You should have received a copy of the GNU General Public License *) | ||
(* along with Waterproof-lib. If not, see <https://www.gnu.org/licenses/>. *) | ||
(* *) | ||
(******************************************************************************) | ||
|
||
Require Import Ltac2.Ltac2. | ||
Require Import Ltac2.Message. | ||
|
||
Require Import Waterproof.Tactics. | ||
Require Import Waterproof.Automation. | ||
|
||
(** Test 0: This should be the expected behavior. *) | ||
Goal (forall n : nat, n = n) -> True. | ||
Proof. | ||
intro H. | ||
Use n := 3 in (H). | ||
It holds that (3 = 3). | ||
Abort. | ||
|
||
(** Test 1: This should fail as the wrong variable name is chosen. *) | ||
Goal (forall n : nat, n = n) -> True. | ||
Proof. | ||
intro H. | ||
Fail Use m := (3) in (H). | ||
Abort. | ||
|
||
(** Test 2: This should fail because the wrong goal is specified. *) | ||
Goal (forall n : nat, n = n) -> True. | ||
Proof. | ||
intro H. | ||
Use n := (3) in (H). | ||
Fail It holds that (True). | ||
Abort. | ||
|
||
(** Test 3: This should fail because first the wrapper needs to be resolved. *) | ||
Goal (forall n : nat, n = n) -> True. | ||
Proof. | ||
intro H. | ||
Use n := (3) in (H). | ||
Fail exact I. | ||
Abort. | ||
|
||
(** It should be possible to use an outside lemma *) | ||
Local Parameter F : nat -> nat. | ||
Local Parameter F_identity : forall n : nat, F n = n. | ||
|
||
Goal True. | ||
Proof. | ||
Fail It holds that (F 3 = 3). | ||
Use n := (5) in (F_identity). | ||
It holds that (F 5 = 5). | ||
Abort. | ||
|
||
(** Test 4: cannot use specialize tactic for function, | ||
throw readable error message stating as much. *) | ||
Definition f : nat -> nat := fun (n : nat) => n. | ||
Goal False. | ||
Proof. | ||
Fail Use n := 5 in (f). | ||
Abort. | ||
|
||
(** Test 5: original universal quantifier hypohtesis left unchanged. *) | ||
Goal (forall n : nat, n = n) -> True. | ||
Proof. | ||
intro H. | ||
Use n := 3 in (H). | ||
ltac1:(rename H into HH). (* test for hypohtesis without producing output *) | ||
Abort. | ||
|
||
(** Test 6: multiple variable specifications *) | ||
Goal (forall n m : nat, n = m) -> False. | ||
Proof. | ||
intro H. | ||
Use n := 3, m := 4 in (H). | ||
It holds that (3 = 4). | ||
Abort. | ||
|
||
(** Test 7: multiple variable specifications, different order *) | ||
Goal (forall n m : nat, n = m) -> False. | ||
Proof. | ||
intro H. | ||
Use m := 4, n := 3 in (H). | ||
Fail It holds that (4 = 3). (* as expected :) *) | ||
It holds that (3 = 4). | ||
Abort. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
(******************************************************************************) | ||
(* This file is part of Waterproof-lib. *) | ||
(* *) | ||
(* Waterproof-lib is free software: you can redistribute it and/or modify *) | ||
(* it under the terms of the GNU General Public License as published by *) | ||
(* the Free Software Foundation, either version 3 of the License, or *) | ||
(* (at your option) any later version. *) | ||
(* *) | ||
(* Waterproof-lib is distributed in the hope that it will be useful, *) | ||
(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) | ||
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) | ||
(* GNU General Public License for more details. *) | ||
(* *) | ||
(* You should have received a copy of the GNU General Public License *) | ||
(* along with Waterproof-lib. If not, see <https://www.gnu.org/licenses/>. *) | ||
(* *) | ||
(******************************************************************************) | ||
|
||
Require Import Ltac2.Ltac2. | ||
Require Import Ltac2.Message. | ||
|
||
Require Import Util.Init. | ||
Require Import Util.Goals. | ||
Require Import Util.MessagesToUser. | ||
|
||
|
||
(** | ||
Specializes a hypothesis that starts with a for-all statement. | ||
Arguments: | ||
- [s : ident], name of the variable to choose | ||
- [choice : constr], choice for the variable | ||
- [in_hyp : ident], name of the hypothesis to specialize. | ||
Raises fatal exceptions: | ||
- If the hypothesis [in_hyp] does not start with a for-all statement. | ||
*) | ||
|
||
Local Ltac2 _ident_to_hyp_list (ls : (ident * constr) list) : (Std.hypothesis * constr) list | ||
:= List.map (fun (i, x) => (Std.NamedHyp i, x)) ls. | ||
|
||
Local Ltac2 wp_specialize (var_choice_list : (ident * constr) list) (h:constr) := | ||
(* let h := Control.hyp in_hyp in *) | ||
(* let named_hyp := Std.NamedHyp s in *) | ||
let statement := eval unfold type_of in (type_of $h) in | ||
(* let specialized_statement := eval unfold type_of in (type_of ($h $choice)) in *) | ||
lazy_match! statement with | ||
| _ -> ?x => (* Exclude matching on functions (naming codomain necessary) *) | ||
throw (of_string "`Pick ... in (*)` only works if (*) starts with a for-all quantifier.") | ||
| forall _ : _, _ => | ||
let w := Fresh.fresh (Fresh.Free.of_goal ()) @_H in | ||
Std.specialize (h, Std.ExplicitBindings (_ident_to_hyp_list var_choice_list)) | ||
(Some (Std.IntroNaming (Std.IntroIdentifier w))) ; | ||
(* specialize $h with ($named_hyp := $choice) as $w; *) | ||
(* Wrap the goal *) | ||
let constr_w := Control.hyp w in | ||
let type_w := Constr.type constr_w in | ||
apply (StateHyp.unwrap $type_w $constr_w) | ||
| _ => throw (of_string "`Pick ... in (*)` only works if (*) starts with a for-all quantifier.") | ||
end. | ||
(** | ||
Specializes a hypothesis that starts with a for-all statement. | ||
Arguments: | ||
- [s : ident], name of the variable to choose | ||
- [choice : constr], choice for the variable | ||
- [in_hyp : ident], name of the hypothesis to specialize. | ||
Raises fatal exceptions: | ||
- If the hypothesis [in_hyp] does not start with a for-all statement. | ||
*) | ||
Ltac2 Notation "Use" s(list1(seq(ident, ":=", constr), ",")) "in" "(" in_hyp(constr) ")" := | ||
wp_specialize s in_hyp. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters