| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 6495c20 commit 4c6d7e2
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -192,3 +192,30 @@ refine_struct ({ .. } : semigroup α), | |||
| 192 | 192 | { have field := @semigroup.mul, ... }, | |
| 193 | 193 | { have field := @semigroup.mul_assoc, ... }, | |
| 194 | 194 | ``` | |
| 195 | + | ||
| 196 | + ### apply_rules | ||
| 197 | + | ||
| 198 | + `apply_rules hs n` applies the list of lemmas `hs` and `assumption` on the | ||
| 199 | + first goal and the resulting subgoals, iteratively, at most `n` times. | ||
| 200 | + `n` is optional, equal to 50 by default. | ||
| 201 | + `hs` can contain user attributes: in this case all theorems with this | ||
| 202 | + attribute are added to the list of rules. | ||
| 203 | + | ||
| 204 | + For instance: | ||
| 205 | + | ||
| 206 | + ``` | ||
| 207 | + @[user_attribute] | ||
| 208 | + meta def mono_rules : user_attribute := | ||
| 209 | + { name := `mono_rules, | ||
| 210 | + descr := "lemmas usable to prove monotonicity" } | ||
| 211 | + | ||
| 212 | + attribute [mono_rules] add_le_add mul_le_mul_of_nonneg_right | ||
| 213 | + | ||
| 214 | + lemma my_test {a b c d e : real} (h1 : a ≤ b) (h2 : c ≤ d) (h3 : 0 ≤ e) : | ||
| 215 | + a + c * e + a + c + 0 ≤ b + d * e + b + d + e := | ||
| 216 | + -- any of the following lines solve the goal: | ||
| 217 | + add_le_add (add_le_add (add_le_add (add_le_add h1 (mul_le_mul_of_nonneg_right h2 h3)) h1 ) h2) h3 | ||
| 218 | + by apply_rules [add_le_add, mul_le_mul_of_nonneg_right] | ||
| 219 | + by apply_rules [mono_rules] | ||
| 220 | + by apply_rules mono_rules | ||
| 221 | + ``` | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -116,9 +116,9 @@ meta def subst_locals (s : list (expr × expr)) (e : expr) : expr := | |||
| 116 | 116 | (e.abstract_locals (s.map (expr.local_uniq_name ∘ prod.fst)).reverse).instantiate_vars (s.map prod.snd) | |
| 117 | 117 | ||
| 118 | 118 | meta def set_binder : expr → list binder_info → expr | |
| 119 | - | e [] := e | ||
| 120 | - | (expr.pi v _ d b) (bi :: bs) := expr.pi v bi d (set_binder b bs) | ||
| 121 | - | e _ := e | ||
| 119 | + | e [] := e | ||
| 120 | + | (expr.pi v _ d b) (bi :: bs) := expr.pi v bi d (set_binder b bs) | ||
| 121 | + | e _ := e | ||
| 122 | 122 | ||
| 123 | 123 | /-- variation on `assert` where a (possibly incomplete) | |
| 124 | 124 | proof of the assertion is provided as a parameter. | |
@@ -147,28 +147,28 @@ do h' ← assert h p, | |||
| 147 | 147 | return (h' , gs) | |
| 148 | 148 | ||
| 149 | 149 | meta def try_intros : list name → tactic (list name) | |
| 150 | - | [] := do | ||
| 151 | - tgt ← target >>= instantiate_mvars, | ||
| 152 | - if tgt.is_pi then failed | ||
| 153 | - else return [] | ||
| 154 | - | (x::xs) := (intro x >> try_intros xs) <|> pure (x :: xs) | ||
| 150 | + | [] := do | ||
| 151 | + tgt ← target >>= instantiate_mvars, | ||
| 152 | + if tgt.is_pi then failed | ||
| 153 | + else return [] | ||
| 154 | + | (x::xs) := (intro x >> try_intros xs) <|> pure (x :: xs) | ||
| 155 | 155 | ||
| 156 | 156 | meta def ext1 (xs : list name) : tactic (list name) := | |
| 157 | 157 | do ls ← attribute.get_instances `extensionality, | |
| 158 | 158 | ls.any_of (λ l, applyc l), | |
| 159 | 159 | try_intros xs | |
| 160 | 160 | ||
| 161 | 161 | meta def ext : list name → option ℕ → tactic unit | |
| 162 | - | _ (some 0) := return () | ||
| 163 | - | xs n := focus1 (do ys ← ext1 xs, ext ys (nat.pred <$> n) <|> return ()) | ||
| 162 | + | _ (some 0) := return () | ||
| 163 | + | xs n := focus1 (do ys ← ext1 xs, ext ys (nat.pred <$> n) <|> return ()) | ||
| 164 | 164 | ||
| 165 | 165 | meta def var_names : expr → list name | |
| 166 | - | (expr.pi n _ _ b) := n :: var_names b | ||
| 167 | - | _ := [] | ||
| 166 | + | (expr.pi n _ _ b) := n :: var_names b | ||
| 167 | + | _ := [] | ||
| 168 | 168 | ||
| 169 | 169 | meta def drop_binders : expr → tactic expr | |
| 170 | - | (expr.pi n bi t b) := b.instantiate_var <$> mk_local' n bi t >>= drop_binders | ||
| 171 | - | e := pure e | ||
| 170 | + | (expr.pi n bi t b) := b.instantiate_var <$> mk_local' n bi t >>= drop_binders | ||
| 171 | + | e := pure e | ||
| 172 | 172 | ||
| 173 | 173 | meta def subobject_names (struct_n : name) : tactic (list name × list name) := | |
| 174 | 174 | do env ← get_env, | |
@@ -191,8 +191,47 @@ dlist.to_list <$> expanded_field_list' struct_n | |||
| 191 | 191 | open nat | |
| 192 | 192 | ||
| 193 | 193 | meta def mk_mvar_list : ℕ → tactic (list expr) | |
| 194 | - | 0 := pure [] | ||
| 195 | - | (succ n) := (::) <$> mk_mvar <*> mk_mvar_list n | ||
| 194 | + | 0 := pure [] | ||
| 195 | + | (succ n) := (::) <$> mk_mvar <*> mk_mvar_list n | ||
| 196 | + | ||
| 197 | + /--`iterate_at_most_on_all_goals n t`: repeat the given tactic at most `n` times on all goals, | ||
| 198 | + or until it fails. Always succeeds. -/ | ||
| 199 | + meta def iterate_at_most_on_all_goals : nat → tactic unit → tactic unit | ||
| 200 | + | 0 tac := trace "maximal iterations reached" | ||
| 201 | + | (succ n) tac := tactic.all_goals $ (do tac, iterate_at_most_on_all_goals n tac) <|> skip | ||
| 202 | + | ||
| 203 | + /--`iterate_at_most_on_subgoals n t`: repeat the tactic `t` at most `n` times on the first | ||
| 204 | + goal and on all subgoals thus produced, or until it fails. Fails iff `t` fails on | ||
| 205 | + current goal. -/ | ||
| 206 | + meta def iterate_at_most_on_subgoals : nat → tactic unit → tactic unit | ||
| 207 | + | 0 tac := trace "maximal iterations reached" | ||
| 208 | + | (succ n) tac := focus1 (do tac, iterate_at_most_on_all_goals n tac) | ||
| 209 | + | ||
| 210 | + /--`apply_list l`: try to apply the tactics in the list `l` on the first goal, and | ||
| 211 | + fail if none succeeds -/ | ||
| 212 | + meta def apply_list_expr : list expr → tactic unit | ||
| 213 | + | [] := fail "no matching rule" | ||
| 214 | + | (h::t) := do interactive.concat_tags (apply h) <|> apply_list_expr t | ||
| 215 | + | ||
| 216 | + /-- constructs a list of expressions given a list of p-expressions, as follows: | ||
| 217 | + - if the p-expression is the name of a theorem, use `i_to_expr_for_apply` on it | ||
| 218 | + - if the p-expression is a user attribute, add all the theorems with this attribute | ||
| 219 | + to the list.-/ | ||
| 220 | + meta def build_list_expr_for_apply : list pexpr → tactic (list expr) | ||
| 221 | + | [] := return [] | ||
| 222 | + | (h::t) := do | ||
| 223 | + tail ← build_list_expr_for_apply t, | ||
| 224 | + a ← i_to_expr_for_apply h, | ||
| 225 | + (do l ← attribute.get_instances (expr.const_name a), | ||
| 226 | + m ← list.mmap mk_const l, | ||
| 227 | + return (m.append tail)) | ||
| 228 | + <|> return (a::tail) | ||
| 229 | + | ||
| 230 | + /--`apply_rules hs n`: apply the list of rules `hs` (given as pexpr) and `assumption` on the | ||
| 231 | + first goal and the resulting subgoals, iteratively, at most `n` times -/ | ||
| 232 | + meta def apply_rules (hs : list pexpr) (n : nat) : tactic unit := | ||
| 233 | + do l ← build_list_expr_for_apply hs, | ||
| 234 | + iterate_at_most_on_subgoals n (assumption <|> apply_list_expr l) | ||
| 196 | 235 | ||
| 197 | 236 | meta def replace (h : name) (p : pexpr) : tactic unit := | |
| 198 | 237 | do h' ← get_local h, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -431,5 +431,31 @@ meta def apply_field : tactic unit := | |||
| 431 | 431 | propagate_tags $ | |
| 432 | 432 | get_current_field >>= applyc | |
| 433 | 433 | ||
| 434 | + /--`apply_rules hs n`: apply the list of rules `hs` (given as pexpr) and `assumption` on the | ||
| 435 | + first goal and the resulting subgoals, iteratively, at most `n` times. | ||
| 436 | + `n` is 50 by default. `hs` can contain user attributes: in this case all theorems with this | ||
| 437 | + attribute are added to the list of rules. | ||
| 438 | + | ||
| 439 | + example, with or without user attribute: | ||
| 440 | + ``` | ||
| 441 | + @[user_attribute] | ||
| 442 | + meta def mono_rules : user_attribute := | ||
| 443 | + { name := `mono_rules, | ||
| 444 | + descr := "lemmas usable to prove monotonicity" } | ||
| 445 | + | ||
| 446 | + attribute [mono_rules] add_le_add mul_le_mul_of_nonneg_right | ||
| 447 | + | ||
| 448 | + lemma my_test {a b c d e : real} (h1 : a ≤ b) (h2 : c ≤ d) (h3 : 0 ≤ e) : | ||
| 449 | + a + c * e + a + c + 0 ≤ b + d * e + b + d + e := | ||
| 450 | + by apply_rules mono_rules | ||
| 451 | + -- any of the following lines would also work: | ||
| 452 | + -- add_le_add (add_le_add (add_le_add (add_le_add h1 (mul_le_mul_of_nonneg_right h2 h3)) h1 ) h2) h3 | ||
| 453 | + -- by apply_rules [add_le_add, mul_le_mul_of_nonneg_right] | ||
| 454 | + -- by apply_rules [mono_rules] | ||
| 455 | + ``` | ||
| 456 | + -/ | ||
| 457 | + meta def apply_rules (hs : parse pexpr_list_or_texpr) (n : nat := 50) : tactic unit := | ||
| 458 | + tactic.apply_rules hs n | ||
| 459 | + | ||
| 434 | 460 | end interactive | |
| 435 | 461 | end tactic | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -454,3 +454,29 @@ begin | |||
| 454 | 454 | end | |
| 455 | 455 | ||
| 456 | 456 | end ext | |
| 457 | + | ||
| 458 | + section apply_rules | ||
| 459 | + | ||
| 460 | + example {a b c d e : nat} (h1 : a ≤ b) (h2 : c ≤ d) (h3 : 0 ≤ e) : | ||
| 461 | + a + c * e + a + c + 0 ≤ b + d * e + b + d + e := | ||
| 462 | + add_le_add (add_le_add (add_le_add (add_le_add h1 (mul_le_mul_of_nonneg_right h2 h3)) h1 ) h2) h3 | ||
| 463 | + | ||
| 464 | + example {a b c d e : nat} (h1 : a ≤ b) (h2 : c ≤ d) (h3 : 0 ≤ e) : | ||
| 465 | + a + c * e + a + c + 0 ≤ b + d * e + b + d + e := | ||
| 466 | + by apply_rules [add_le_add, mul_le_mul_of_nonneg_right] | ||
| 467 | + | ||
| 468 | + @[user_attribute] | ||
| 469 | + meta def mono_rules : user_attribute := | ||
| 470 | + { name := `mono_rules, | ||
| 471 | + descr := "lemmas usable to prove monotonicity" } | ||
| 472 | + attribute [mono_rules] add_le_add mul_le_mul_of_nonneg_right | ||
| 473 | + | ||
| 474 | + example {a b c d e : nat} (h1 : a ≤ b) (h2 : c ≤ d) (h3 : 0 ≤ e) : | ||
| 475 | + a + c * e + a + c + 0 ≤ b + d * e + b + d + e := | ||
| 476 | + by apply_rules [mono_rules] | ||
| 477 | + | ||
| 478 | + example {a b c d e : nat} (h1 : a ≤ b) (h2 : c ≤ d) (h3 : 0 ≤ e) : | ||
| 479 | + a + c * e + a + c + 0 ≤ b + d * e + b + d + e := | ||
| 480 | + by apply_rules mono_rules | ||
| 481 | + | ||
| 482 | + end apply_rules | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments