feat(library/init/meta): add helper functions
This commit is contained in:
parent
2f5159e7eb
commit
5ca18b8d2e
4 changed files with 41 additions and 12 deletions
|
|
@ -21,3 +21,9 @@ infixr ` <|> `:2 := orelse
|
|||
|
||||
@[inline] def guard {f : Type → Type v} [alternative f] (p : Prop) [decidable p] : f unit :=
|
||||
if p then pure () else failure
|
||||
|
||||
/- Later we define a coercion from bool to Prop, but this version will still be useful.
|
||||
Given (t : tactic bool), we can write t >>= guardb -/
|
||||
@[inline] def guardb {f : Type → Type v} [alternative f] : bool → f unit
|
||||
| tt := pure ()
|
||||
| ff := failure
|
||||
|
|
|
|||
|
|
@ -90,6 +90,8 @@ meta constant expr.is_internal_cnstr : expr → option unsigned
|
|||
meta constant expr.get_nat_value : expr → option nat
|
||||
|
||||
meta constant expr.collect_univ_params : expr → list name
|
||||
/-- `occurs e t` returns `tt` iff `e` occurs in `t` -/
|
||||
meta constant expr.occurs : expr → expr → bool
|
||||
|
||||
namespace expr
|
||||
open decidable
|
||||
|
|
@ -109,6 +111,10 @@ meta constant mk_sorry (type : expr) : expr
|
|||
/-- Checks whether e is sorry, and returns its type. -/
|
||||
meta constant is_sorry (e : expr) : option expr
|
||||
|
||||
meta def is_var : expr → bool
|
||||
| (var _) := tt
|
||||
| _ := ff
|
||||
|
||||
meta def app_of_list : expr → list expr → expr
|
||||
| f [] := f
|
||||
| f (p::ps) := app_of_list (f p) ps
|
||||
|
|
|
|||
|
|
@ -115,27 +115,22 @@ end
|
|||
namespace tactic
|
||||
variables {α : Type u}
|
||||
|
||||
meta def try_core (t : tactic α) : tactic bool :=
|
||||
meta def try_core (t : tactic α) : tactic (option α) :=
|
||||
λ s, tactic_result.cases_on (t s)
|
||||
(λ a, success tt)
|
||||
(λ e ref s', success ff s)
|
||||
(λ a, success (some a))
|
||||
(λ e ref s', success none s)
|
||||
|
||||
meta def skip : tactic unit :=
|
||||
success ()
|
||||
|
||||
meta def try (t : tactic α) : tactic unit :=
|
||||
try_core t >> skip
|
||||
try_core t >>[tactic] skip
|
||||
|
||||
meta def fail_if_success {α : Type u} (t : tactic α) : tactic unit :=
|
||||
λ s, tactic_result.cases_on (t s)
|
||||
(λ a s, mk_exception "fail_if_success combinator failed, given tactic succeeded" none s)
|
||||
(λ e ref s', success () s)
|
||||
|
||||
open list
|
||||
meta def foreach : list α → (α → tactic unit) → tactic unit
|
||||
| [] fn := skip
|
||||
| (e::es) fn := do fn e, foreach es fn
|
||||
|
||||
open nat
|
||||
/- (repeat_at_most n t): repeat the given tactic at most n times or until t fails -/
|
||||
meta def repeat_at_most : nat → tactic unit → tactic unit
|
||||
|
|
@ -743,7 +738,7 @@ private meta def any_goals_core (tac : tactic unit) : list expr → list expr
|
|||
do set_goals [g],
|
||||
succeeded ← try_core tac,
|
||||
new_gs ← get_goals,
|
||||
any_goals_core gs (ac ++ new_gs) (succeeded || progress)
|
||||
any_goals_core gs (ac ++ new_gs) (succeeded^.is_some || progress)
|
||||
|
||||
/- Apply the given tactic to any goal where it succeeds. The tactic succeeds only if
|
||||
tac succeeds for at least one goal. -/
|
||||
|
|
@ -972,6 +967,22 @@ meta def list_name.to_expr : list name → tactic expr
|
|||
notation [parsing_only] `command`:max := tactic unit
|
||||
|
||||
open tactic
|
||||
|
||||
namespace list
|
||||
|
||||
meta def for_each {α} : list α → (α → tactic unit) → tactic unit
|
||||
| [] fn := skip
|
||||
| (e::es) fn := do fn e, for_each es fn
|
||||
|
||||
meta def any_of {α β} : list α → (α → tactic β) → tactic β
|
||||
| [] fn := failed
|
||||
| (e::es) fn := do opt_b ← try_core (fn e),
|
||||
match opt_b with
|
||||
| some b := return b
|
||||
| none := any_of es fn
|
||||
end
|
||||
end list
|
||||
|
||||
/-
|
||||
Define id_locked using meta-programming because we don't have
|
||||
syntax for setting reducibility_hints.
|
||||
|
|
|
|||
|
|
@ -6,14 +6,15 @@ Author: Leonardo de Moura
|
|||
*/
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include "library/locals.h"
|
||||
#include "library/sorry.h"
|
||||
#include "kernel/expr.h"
|
||||
#include "kernel/free_vars.h"
|
||||
#include "kernel/instantiate.h"
|
||||
#include "kernel/abstract.h"
|
||||
#include "kernel/for_each_fn.h"
|
||||
#include "kernel/replace_fn.h"
|
||||
#include "library/locals.h"
|
||||
#include "library/sorry.h"
|
||||
#include "library/util.h"
|
||||
#include "library/expr_lt.h"
|
||||
#include "library/deep_copy.h"
|
||||
#include "library/comp_val.h"
|
||||
|
|
@ -428,6 +429,10 @@ vm_obj expr_is_sorry(vm_obj const & e_) {
|
|||
return to_obj(is_sorry(e) ? some(sorry_type(e)) : none_expr());
|
||||
}
|
||||
|
||||
vm_obj expr_occurs(vm_obj const & e1, vm_obj const & e2) {
|
||||
return mk_vm_bool(occurs(to_expr(e1), to_expr(e2)));
|
||||
}
|
||||
|
||||
void initialize_vm_expr() {
|
||||
DECLARE_VM_BUILTIN(name({"expr", "var"}), expr_var);
|
||||
DECLARE_VM_BUILTIN(name({"expr", "sort"}), expr_sort);
|
||||
|
|
@ -461,6 +466,7 @@ void initialize_vm_expr() {
|
|||
DECLARE_VM_BUILTIN(name({"expr", "lower_vars"}), expr_lower_vars);
|
||||
DECLARE_VM_BUILTIN(name({"expr", "hash"}), expr_hash);
|
||||
DECLARE_VM_BUILTIN(name({"expr", "copy_pos_info"}), expr_copy_pos_info);
|
||||
DECLARE_VM_BUILTIN(name({"expr", "occurs"}), expr_occurs);
|
||||
DECLARE_VM_BUILTIN(name({"expr", "collect_univ_params"}), expr_collect_univ_params);
|
||||
DECLARE_VM_CASES_BUILTIN(name({"expr", "cases_on"}), expr_cases_on);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue