/* Copyright (c) 2014 Microsoft Corporation. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Author: Leonardo de Moura */ #pragma once #include #include #include "library/tactic/tactic.h" namespace lean { namespace inversion { /** \brief When we apply the inversion tactic/procedure on a hypothesis (h : I A j), where I is an inductive datatpe, the hypothesis is "broken" into cases: one for each constructor. Some cases may be in conflict with the type (I A j) and may be suppressed. Example of conflict: given the vector type inductive vector (A : Type) : nat → Type := nil {} : vector A zero, cons : Π {n : nat}, A → vector A n → vector A (succ n) Then, (h : vector A (succ n)) is in conflict with constructor nil. The user may provide possible implementations (example: in the form of equations). Each possible implementation is associated with a case/constructor. The inversion tactic/procedure distributes the implementations over cases. The implementations may depend on hypotheses that may be modifed by the inversion procedure. The method update_exprs of each implementation is invoked to update the expressions of a given implementation. */ class implementation { public: virtual ~implementation() {} virtual name const & get_constructor_name() const = 0; virtual void update_exprs(std::function const & fn) = 0; }; typedef std::shared_ptr implementation_ptr; typedef list implementation_list; struct result { list m_goals; list m_num_args; list m_implementation_lists; // invariant: length(m_goals) == length(m_num_args); // invariant: length(m_goals) == length(m_implementation_lists); name_generator m_ngen; substitution m_subst; result(list const & gs, list const & num_args, list const & imps, name_generator const & ngen, substitution const & subst); }; optional apply(environment const & env, io_state const & ios, type_checker & tc, goal const & g, name const & n, implementation_list const & imps); } tactic inversion_tactic(name const & n, list const & ids = list()); void initialize_inversion_tactic(); void finalize_inversion_tactic(); }