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"
|
|
|
|
#include "library/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 {
|
|
|
|
/**
|
|
|
|
\brief Object for managing the environment, parser, pretty printer,
|
|
|
|
elaborator, etc.
|
|
|
|
*/
|
|
|
|
class frontend {
|
|
|
|
struct imp;
|
2013-09-17 21:42:44 +00:00
|
|
|
std::shared_ptr<imp> m_ptr;
|
2013-08-10 01:00:05 +00:00
|
|
|
explicit frontend(imp * new_ptr);
|
|
|
|
explicit frontend(std::shared_ptr<imp> const & ptr);
|
2013-08-20 20:55:31 +00:00
|
|
|
state & get_state_core();
|
2013-08-10 01:00:05 +00:00
|
|
|
public:
|
|
|
|
frontend();
|
|
|
|
~frontend();
|
|
|
|
|
2013-08-20 00:25:15 +00:00
|
|
|
/**
|
|
|
|
@name Parent/Child frontend management.
|
|
|
|
*/
|
|
|
|
/*@{*/
|
2013-08-10 01:00:05 +00:00
|
|
|
/**
|
|
|
|
\brief Create a child environment. This frontend object will
|
|
|
|
only allow "read-only" operations until all children frontend
|
|
|
|
objects are deleted.
|
|
|
|
*/
|
|
|
|
frontend mk_child() const;
|
|
|
|
|
|
|
|
/** \brief Return true iff this fronted has children frontend. */
|
|
|
|
bool has_children() const;
|
|
|
|
|
|
|
|
/** \brief Return true iff this frontend has a parent frontend. */
|
|
|
|
bool has_parent() const;
|
|
|
|
|
|
|
|
/** \brief Return parent frontend */
|
|
|
|
frontend parent() const;
|
2013-08-20 00:25:15 +00:00
|
|
|
/*@}*/
|
2013-08-10 01:00:05 +00:00
|
|
|
|
2013-08-20 00:25:15 +00:00
|
|
|
/**
|
|
|
|
@name Environment API
|
|
|
|
*/
|
|
|
|
/*@{*/
|
2013-08-10 01:00:05 +00:00
|
|
|
/** \brief Coercion frontend -> environment. */
|
2013-08-17 03:39:24 +00:00
|
|
|
environment const & get_environment() const;
|
|
|
|
operator environment const &() const { return get_environment(); }
|
2013-08-10 01:00:05 +00:00
|
|
|
|
|
|
|
level add_uvar(name const & n, level const & l);
|
|
|
|
level add_uvar(name const & n);
|
|
|
|
level get_uvar(name const & n) const;
|
2013-08-17 17:55:42 +00:00
|
|
|
void add_definition(name const & n, expr const & t, expr const & v, bool opaque = false);
|
|
|
|
void add_theorem(name const & n, expr const & t, expr const & v);
|
|
|
|
void add_definition(name const & n, expr const & v, bool opaque = false);
|
|
|
|
void add_axiom(name const & n, expr const & t);
|
|
|
|
void add_var(name const & n, expr const & t);
|
|
|
|
object const & get_object(name const & n) const;
|
|
|
|
object const & find_object(name const & n) const;
|
|
|
|
bool has_object(name const & n) const;
|
2013-08-18 01:13:55 +00:00
|
|
|
typedef environment::object_iterator object_iterator;
|
|
|
|
object_iterator begin_objects() const;
|
|
|
|
object_iterator end_objects() const;
|
|
|
|
object_iterator begin_local_objects() const;
|
|
|
|
object_iterator end_local_objects() const;
|
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-08-30 22:56:04 +00:00
|
|
|
void mark_implicit_arguments(expr const & n, std::initializer_list<bool> const & l) { mark_implicit_arguments(const_name(n), 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.
|
|
|
|
Return the null expression if there is no coercion from \c from_type to
|
|
|
|
\c to_type.
|
2013-09-01 23:59:15 +00:00
|
|
|
*/
|
2013-10-24 21:38:09 +00:00
|
|
|
expr get_coercion(expr const & from_type, expr const & to_type) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
\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.
|
|
|
|
*/
|
|
|
|
/*@{*/
|
|
|
|
state const & get_state() const;
|
|
|
|
operator state const &() const { return get_state(); }
|
|
|
|
void set_options(options const & opts);
|
2013-08-20 20:55:31 +00:00
|
|
|
template<typename T> void set_option(name const & n, T const & v) { get_state_core().set_option(n, v); }
|
2013-08-20 19:19:28 +00:00
|
|
|
void set_regular_channel(std::shared_ptr<output_channel> const & out);
|
|
|
|
void set_diagnostic_channel(std::shared_ptr<output_channel> const & out);
|
|
|
|
/*@}*/
|
2013-08-24 23:11:35 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
@name Interrupts.
|
|
|
|
*/
|
|
|
|
void set_interrupt(bool flag);
|
|
|
|
void interrupt() { set_interrupt(true); }
|
|
|
|
void reset_interrupt() { set_interrupt(false); }
|
|
|
|
/*@}*/
|
2013-08-10 01:00:05 +00:00
|
|
|
};
|
|
|
|
}
|