102 lines
4.7 KiB
C++
102 lines
4.7 KiB
C++
/*
|
|
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 <utility>
|
|
#include "util/lua.h"
|
|
#include "kernel/environment.h"
|
|
#include "library/expr_pair.h"
|
|
#include "library/io_state.h"
|
|
|
|
namespace lean {
|
|
enum class coercion_class_kind { User, Sort, Fun };
|
|
/**
|
|
\brief A coercion is a mapping between classes.
|
|
We support three kinds of classes: User, Sort, Function.
|
|
*/
|
|
class coercion_class {
|
|
coercion_class_kind m_kind;
|
|
name m_name; // relevant only if m_kind == User
|
|
coercion_class(coercion_class_kind k, name const & n = name()):m_kind(k), m_name(n) {}
|
|
public:
|
|
coercion_class():m_kind(coercion_class_kind::Sort) {}
|
|
static coercion_class mk_user(name n);
|
|
static coercion_class mk_sort();
|
|
static coercion_class mk_fun();
|
|
friend bool operator==(coercion_class const & c1, coercion_class const & c2);
|
|
friend bool operator!=(coercion_class const & c1, coercion_class const & c2);
|
|
coercion_class_kind kind() const { return m_kind; }
|
|
name get_name() const { return m_name; }
|
|
};
|
|
|
|
/**
|
|
\brief Add an new coercion in the given environment.
|
|
|
|
There are three kinds of coercions supported
|
|
1- From type C to type D
|
|
type of f must have the form:
|
|
{l1 ... lk} Pi (x1 : A1) ... (xn : An) (y: C.{l1 ... lk} x1 ... xn), D.{L1 ... Lr} t1 ... tm
|
|
- C and D are constants.
|
|
- l1 ... lk are universe level parameters
|
|
- L1 ... Lr are universe level expressions
|
|
- t1 ... tm are level expressions
|
|
|
|
2- From type to sort
|
|
type of f must have the form:
|
|
{l1 ... lk} Pi (x1 : A1) ... (xn : An) (y: C.{l1 ... lk} x1 ... xn) (x : A), B
|
|
|
|
3- From type to function type
|
|
type of f must have the form:
|
|
{l1 ... lk} Pi (x1 : A1) ... (xn : An) (y: C.{l1 ... lk} x1 ... xn), Type.{L}
|
|
|
|
\pre \c f is a constant defined in \c env.
|
|
|
|
\remark \c ios is used to report warning messages.
|
|
|
|
\remark if persistent == true, then coercion is saved in .olean files
|
|
*/
|
|
environment add_coercion(environment const & env, name const & f, io_state const & ios, bool persistent = true);
|
|
environment add_coercion(environment const & env, name const & f, name const & C, io_state const & ios,
|
|
bool persistent = true);
|
|
/** \brief If \c f is a coercion, then return the name of the 'from-class' and the number of
|
|
class parameters.
|
|
*/
|
|
optional<pair<name, unsigned>> is_coercion(environment const & env, name const & f);
|
|
optional<pair<name, unsigned>> is_coercion(environment const & env, expr const & f);
|
|
/** \brief Return true iff the given environment has coercions from a user-class named \c C. */
|
|
bool has_coercions_from(environment const & env, name const & C);
|
|
bool has_coercions_from(environment const & env, expr const & C);
|
|
/** \brief Return true iff the given environment has coercions to a user-class named \c D. */
|
|
bool has_coercions_to(environment const & env, name const & D);
|
|
bool has_coercions_to_sort(environment const & env);
|
|
bool has_coercions_to_fun(environment const & env);
|
|
/**
|
|
\brief Return a coercion (if it exists) from (C_name.{l1 lk} t_1 ... t_n) to the class named D.
|
|
The coercion is a unary function that takes a term of type (C_name.{l1 lk} t_1 ... t_n) and returns
|
|
and element of type (D.{L_1 L_o} s_1 ... s_m)
|
|
*/
|
|
list<expr> get_coercions(environment const & env, expr const & C, name const & D);
|
|
list<expr> get_coercions_to_sort(environment const & env, expr const & C);
|
|
list<expr> get_coercions_to_fun(environment const & env, expr const & C);
|
|
/**
|
|
\brief Return all coercions C >-> D for the type C of the form (C_name.{l1 ... lk} t_1 ... t_n)
|
|
The result is a tuple (class D, coercion, coercion type), and is stored in the result buffer \c result.
|
|
The Boolean result is true if at least one pair is added to \c result.
|
|
|
|
\remark The most recent coercions occur first.
|
|
*/
|
|
bool get_coercions_from(environment const & env, expr const & C, buffer<std::tuple<coercion_class, expr, expr>> & result);
|
|
|
|
typedef std::function<void(name const &, name const &, expr const &, level_param_names const &, unsigned)> coercion_user_fn;
|
|
typedef std::function<void(name const &, expr const &, level_param_names const &, unsigned)> coercion_sort_fn;
|
|
typedef std::function<void(name const &, expr const &, level_param_names const &, unsigned)> coercion_fun_fn;
|
|
void for_each_coercion_user(environment const & env, coercion_user_fn const & f);
|
|
void for_each_coercion_sort(environment const & env, coercion_sort_fn const & f);
|
|
void for_each_coercion_fun(environment const & env, coercion_fun_fn const & f);
|
|
void open_coercion(lua_State * L);
|
|
void initialize_coercion();
|
|
void finalize_coercion();
|
|
}
|