2013-08-10 01:00:05 +00:00
|
|
|
/*
|
|
|
|
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
|
|
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
|
|
|
|
|
|
Author: Leonardo de Moura
|
|
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <memory>
|
2013-09-13 23:14:24 +00:00
|
|
|
#include <vector>
|
2013-09-13 03:04:10 +00:00
|
|
|
#include "kernel/environment.h"
|
2013-11-21 23:51:29 +00:00
|
|
|
#include "library/io_state.h"
|
2013-10-24 21:38:09 +00:00
|
|
|
#include "library/expr_pair.h"
|
2013-09-13 03:09:35 +00:00
|
|
|
#include "frontends/lean/operator_info.h"
|
2013-08-10 01:00:05 +00:00
|
|
|
|
|
|
|
namespace lean {
|
|
|
|
/**
|
2013-11-07 18:00:12 +00:00
|
|
|
\brief Wrapper for environment/state that provides additional objects
|
|
|
|
that are specific to the Lean frontend.
|
|
|
|
|
|
|
|
This wrapper provides APIs for accessing/using the Lean frontend
|
|
|
|
extension data in the environment.
|
2013-08-10 01:00:05 +00:00
|
|
|
*/
|
|
|
|
class frontend {
|
2013-11-07 18:00:12 +00:00
|
|
|
environment m_env;
|
2013-11-21 23:51:29 +00:00
|
|
|
io_state m_state;
|
2013-08-10 01:00:05 +00:00
|
|
|
public:
|
|
|
|
frontend();
|
2013-11-21 23:51:29 +00:00
|
|
|
frontend(environment const & env, io_state const & s);
|
2013-08-10 01:00:05 +00:00
|
|
|
|
2013-11-07 18:00:12 +00:00
|
|
|
frontend mk_child() const { return frontend(m_env.mk_child(), m_state); }
|
|
|
|
bool has_children() const { return m_env.has_children(); }
|
|
|
|
bool has_parent() const { return m_env.has_parent(); }
|
2013-08-10 01:00:05 +00:00
|
|
|
|
2013-11-07 18:00:12 +00:00
|
|
|
environment const & get_environment() const { return m_env; }
|
|
|
|
operator environment const &() const { return get_environment(); }
|
2013-11-07 19:29:01 +00:00
|
|
|
environment & get_environment() { return m_env; }
|
|
|
|
operator environment &() { return get_environment(); }
|
2013-08-10 01:00:05 +00:00
|
|
|
|
2013-08-20 00:25:15 +00:00
|
|
|
/**
|
|
|
|
@name Environment API
|
|
|
|
*/
|
|
|
|
/*@{*/
|
2013-11-07 18:00:12 +00:00
|
|
|
level add_uvar(name const & n, level const & l) { return m_env.add_uvar(n, l); }
|
|
|
|
level add_uvar(name const & n) { return m_env.add_uvar(n); }
|
|
|
|
level get_uvar(name const & n) const { return m_env.get_uvar(n); }
|
|
|
|
void add_definition(name const & n, expr const & t, expr const & v, bool opaque = false) { m_env.add_definition(n, t, v, opaque); }
|
|
|
|
void add_theorem(name const & n, expr const & t, expr const & v) { m_env.add_theorem(n, t, v); }
|
|
|
|
void add_definition(name const & n, expr const & v, bool opaque = false) { m_env.add_definition(n, v, opaque); }
|
|
|
|
void add_axiom(name const & n, expr const & t) { m_env.add_axiom(n, t); }
|
|
|
|
void add_var(name const & n, expr const & t) { m_env.add_var(n, t); }
|
2013-12-08 22:37:38 +00:00
|
|
|
object get_object(name const & n) const { return m_env.get_object(n); }
|
|
|
|
optional<object> find_object(name const & n) const { return m_env.find_object(n); }
|
2013-11-07 18:00:12 +00:00
|
|
|
bool has_object(name const & n) const { return m_env.has_object(n); }
|
2013-08-18 01:13:55 +00:00
|
|
|
typedef environment::object_iterator object_iterator;
|
2013-11-07 18:00:12 +00:00
|
|
|
object_iterator begin_objects() const { return m_env.begin_objects(); }
|
|
|
|
object_iterator end_objects() const { return m_env.end_objects(); }
|
|
|
|
object_iterator begin_local_objects() const { return m_env.begin_local_objects(); }
|
|
|
|
object_iterator end_local_objects() const { return m_env.end_local_objects(); }
|
2013-08-20 00:25:15 +00:00
|
|
|
/*@}*/
|
2013-08-10 01:00:05 +00:00
|
|
|
|
2013-08-16 01:54:01 +00:00
|
|
|
/**
|
2013-08-20 00:25:15 +00:00
|
|
|
@name Notation for parsing and pretty printing.
|
|
|
|
*/
|
|
|
|
/*@{*/
|
|
|
|
void add_infix(name const & opn, unsigned precedence, expr const & d);
|
|
|
|
void add_infixl(name const & opn, unsigned precedence, expr const & d);
|
|
|
|
void add_infixr(name const & opn, unsigned precedence, expr const & d);
|
|
|
|
void add_prefix(name const & opn, unsigned precedence, expr const & d);
|
|
|
|
void add_postfix(name const & opn, unsigned precedence, expr const & d);
|
|
|
|
void add_mixfixl(unsigned sz, name const * opns, unsigned precedence, expr const & d);
|
|
|
|
void add_mixfixr(unsigned sz, name const * opns, unsigned precedence, expr const & d);
|
|
|
|
void add_mixfixc(unsigned sz, name const * opns, unsigned precedence, expr const & d);
|
2013-08-27 17:09:46 +00:00
|
|
|
void add_mixfixo(unsigned sz, name const * opns, unsigned precedence, expr const & d);
|
2013-09-04 03:39:54 +00:00
|
|
|
void add_mixfixl(std::initializer_list<name> const & l, unsigned p, expr const & d) { add_mixfixl(l.size(), l.begin(), p, d); }
|
|
|
|
void add_mixfixr(std::initializer_list<name> const & l, unsigned p, expr const & d) { add_mixfixr(l.size(), l.begin(), p, d); }
|
|
|
|
void add_mixfixc(std::initializer_list<name> const & l, unsigned p, expr const & d) { add_mixfixc(l.size(), l.begin(), p, d); }
|
|
|
|
void add_mixfixo(std::initializer_list<name> const & l, unsigned p, expr const & d) { add_mixfixo(l.size(), l.begin(), p, d); }
|
2013-08-20 00:25:15 +00:00
|
|
|
/**
|
|
|
|
\brief Return the operator (if one exists) associated with the
|
|
|
|
given expression.
|
2013-08-16 01:54:01 +00:00
|
|
|
|
2013-08-20 00:25:15 +00:00
|
|
|
\remark If an operator is not associated with \c e, then
|
2013-08-17 17:55:42 +00:00
|
|
|
return the null operator.
|
2013-08-20 00:25:15 +00:00
|
|
|
|
|
|
|
\remark This is used for pretty printing.
|
2013-09-03 17:09:19 +00:00
|
|
|
|
|
|
|
\remark If unicode is false, then only operators containing
|
|
|
|
safe ASCII chars are considered.
|
2013-08-16 01:54:01 +00:00
|
|
|
*/
|
2013-09-03 17:09:19 +00:00
|
|
|
operator_info find_op_for(expr const & e, bool unicode) const;
|
2013-08-20 00:25:15 +00:00
|
|
|
/**
|
|
|
|
\brief Return the operator (if one exists) that can appear at
|
|
|
|
the beginning of a language construct.
|
2013-08-18 01:13:55 +00:00
|
|
|
|
2013-08-20 00:25:15 +00:00
|
|
|
\remark If there isn't a nud operator starting with \c n, then
|
|
|
|
return the null operator.
|
|
|
|
|
|
|
|
\remark This is used for parsing.
|
|
|
|
*/
|
2013-08-18 01:13:55 +00:00
|
|
|
operator_info find_nud(name const & n) const;
|
2013-08-20 00:25:15 +00:00
|
|
|
/**
|
|
|
|
\brief Return the operator (if one exists) that can appear
|
|
|
|
inside of a language construct.
|
2013-08-18 01:13:55 +00:00
|
|
|
|
2013-08-20 00:25:15 +00:00
|
|
|
\remark If there isn't a led operator starting with \c n, then
|
|
|
|
return the null operator.
|
|
|
|
|
|
|
|
\remark This is used for parsing.
|
|
|
|
*/
|
2013-08-18 01:13:55 +00:00
|
|
|
operator_info find_led(name const & n) const;
|
2013-08-20 00:25:15 +00:00
|
|
|
/*@}*/
|
2013-08-20 19:19:28 +00:00
|
|
|
|
2013-08-26 16:04:17 +00:00
|
|
|
/**
|
|
|
|
@name Implicit arguments.
|
|
|
|
*/
|
|
|
|
/**
|
|
|
|
\brief Mark the given arguments of \c n as implicit.
|
2013-08-27 03:21:05 +00:00
|
|
|
The bit-vector array specify the position of the implicit arguments.
|
2013-08-26 16:04:17 +00:00
|
|
|
*/
|
2013-08-27 03:21:05 +00:00
|
|
|
void mark_implicit_arguments(name const & n, unsigned sz, bool const * mask);
|
|
|
|
void mark_implicit_arguments(name const & n, std::initializer_list<bool> const & l);
|
2013-10-29 22:53:50 +00:00
|
|
|
void mark_implicit_arguments(expr const & n, std::initializer_list<bool> const & l);
|
2013-08-26 16:04:17 +00:00
|
|
|
/** \brief Return true iff \c n has implicit arguments */
|
2013-08-27 01:46:16 +00:00
|
|
|
bool has_implicit_arguments(name const & n) const;
|
2013-08-26 16:04:17 +00:00
|
|
|
/** \brief Return the position of the arguments that are implicit. */
|
2013-08-27 03:21:05 +00:00
|
|
|
std::vector<bool> const & get_implicit_arguments(name const & n) const;
|
2013-08-26 16:04:17 +00:00
|
|
|
/**
|
|
|
|
\brief This frontend associates an definition with each
|
|
|
|
definition (or postulate) that has implicit arguments. The
|
|
|
|
additional definition has explicit arguments, and it is called
|
|
|
|
n::explicit. The explicit version can be used when the Lean
|
|
|
|
frontend can't figure out the value for the implicit
|
|
|
|
arguments.
|
|
|
|
*/
|
2013-08-27 01:46:16 +00:00
|
|
|
name const & get_explicit_version(name const & n) const;
|
2013-09-07 00:58:45 +00:00
|
|
|
/**
|
|
|
|
\brief Return true iff \c n is the name of the "explicit"
|
|
|
|
version of an object with implicit arguments
|
|
|
|
*/
|
|
|
|
bool is_explicit(name const & n) const;
|
2013-08-26 16:04:17 +00:00
|
|
|
/*@}*/
|
|
|
|
|
2013-09-01 23:59:15 +00:00
|
|
|
/**
|
|
|
|
@name Coercions
|
|
|
|
|
|
|
|
We support a very basic form of coercion. It is an expression
|
|
|
|
with type T1 -> T2. This expression can be used to convert
|
|
|
|
an expression of type T1 into an expression of type T2 whenever
|
|
|
|
T2 is expected, but T1 was provided.
|
|
|
|
*/
|
|
|
|
/**
|
|
|
|
\brief Add a new coercion to the frontend.
|
|
|
|
It throws an exception if f does not have type T1 -> T2, or if there is already a
|
|
|
|
coercion from T1 to T2.
|
|
|
|
*/
|
|
|
|
void add_coercion(expr const & f);
|
2013-10-24 21:38:09 +00:00
|
|
|
|
2013-09-01 23:59:15 +00:00
|
|
|
/**
|
2013-10-24 21:38:09 +00:00
|
|
|
\brief Return a coercion from given_type to expected_type if it exists.
|
2013-09-01 23:59:15 +00:00
|
|
|
*/
|
2013-12-08 07:21:07 +00:00
|
|
|
optional<expr> get_coercion(expr const & from_type, expr const & to_type) const;
|
2013-10-24 21:38:09 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
\brief Return the list of coercions for the given type.
|
|
|
|
The result is a list of pairs (to_type, function).
|
|
|
|
*/
|
|
|
|
list<expr_pair> get_coercions(expr const & from_type) const;
|
|
|
|
|
2013-09-01 23:59:15 +00:00
|
|
|
/**
|
|
|
|
\brief Return true iff the given expression is a coercion. That is, it was added using
|
|
|
|
\c add_coercion.
|
|
|
|
*/
|
2013-09-02 02:08:49 +00:00
|
|
|
bool is_coercion(expr const & f) const;
|
2013-09-01 23:59:15 +00:00
|
|
|
/*@}*/
|
|
|
|
|
2013-08-20 19:19:28 +00:00
|
|
|
/**
|
|
|
|
@name State management.
|
|
|
|
*/
|
|
|
|
/*@{*/
|
2013-11-21 23:51:29 +00:00
|
|
|
io_state const & get_state() const { return m_state; }
|
|
|
|
operator io_state const &() const { return m_state; }
|
|
|
|
io_state & get_state() { return m_state; }
|
|
|
|
operator io_state &() { return m_state; }
|
2013-11-07 18:00:12 +00:00
|
|
|
options get_options() const { return m_state.get_options(); }
|
|
|
|
void set_options(options const & opts) { return m_state.set_options(opts); }
|
|
|
|
template<typename T> void set_option(name const & n, T const & v) { m_state.set_option(n, v); }
|
|
|
|
void set_regular_channel(std::shared_ptr<output_channel> const & out) { m_state.set_regular_channel(out); }
|
|
|
|
void set_diagnostic_channel(std::shared_ptr<output_channel> const & out) { m_state.set_diagnostic_channel(out); }
|
2013-08-20 19:19:28 +00:00
|
|
|
/*@}*/
|
2013-08-10 01:00:05 +00:00
|
|
|
};
|
|
|
|
}
|