feat(library/init/meta): add helper functions

This commit is contained in:
Leonardo de Moura 2017-02-11 16:52:06 -08:00
parent 2f5159e7eb
commit 5ca18b8d2e
4 changed files with 41 additions and 12 deletions

View file

@ -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

View file

@ -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

View file

@ -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.

View file

@ -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);