2013-07-22 11:03:46 +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
|
2013-09-13 23:14:24 +00:00
|
|
|
#include <algorithm>
|
2013-07-22 11:03:46 +00:00
|
|
|
#include <iostream>
|
|
|
|
#include <limits>
|
2013-09-13 10:35:29 +00:00
|
|
|
#include <utility>
|
2013-10-26 18:07:06 +00:00
|
|
|
#include <tuple>
|
2013-12-28 09:16:50 +00:00
|
|
|
#include <string>
|
2013-12-09 22:56:48 +00:00
|
|
|
#include "util/thread.h"
|
2013-11-27 03:15:49 +00:00
|
|
|
#include "util/lua.h"
|
2013-09-13 03:04:10 +00:00
|
|
|
#include "util/rc.h"
|
|
|
|
#include "util/name.h"
|
|
|
|
#include "util/hash.h"
|
|
|
|
#include "util/buffer.h"
|
2013-09-13 01:25:38 +00:00
|
|
|
#include "util/list_fn.h"
|
2013-12-08 07:21:07 +00:00
|
|
|
#include "util/optional.h"
|
2013-12-28 09:16:50 +00:00
|
|
|
#include "util/serializer.h"
|
2013-09-13 03:04:10 +00:00
|
|
|
#include "util/sexpr/format.h"
|
|
|
|
#include "kernel/level.h"
|
2013-07-22 11:03:46 +00:00
|
|
|
|
|
|
|
namespace lean {
|
2014-02-15 03:55:02 +00:00
|
|
|
class expr;
|
2014-02-16 17:53:55 +00:00
|
|
|
typedef list<level> levels;
|
2013-07-22 11:03:46 +00:00
|
|
|
/* =======================================
|
|
|
|
Expressions
|
2013-08-03 23:09:21 +00:00
|
|
|
expr ::= Var idx
|
2014-02-15 03:55:02 +00:00
|
|
|
| Sort level
|
|
|
|
| Constant name [levels]
|
|
|
|
| Meta name expr
|
|
|
|
| Local name expr
|
|
|
|
| App expr expr
|
2014-02-04 00:52:49 +00:00
|
|
|
| Pair expr expr expr
|
2014-02-15 03:55:02 +00:00
|
|
|
| Fst expr
|
|
|
|
| Snd expr
|
2013-08-03 23:09:21 +00:00
|
|
|
| Lambda name expr expr
|
|
|
|
| Pi name expr expr
|
2014-02-04 00:52:49 +00:00
|
|
|
| Sigma name expr expr
|
2014-02-15 03:55:02 +00:00
|
|
|
| Let name expr? expr expr
|
2013-07-22 11:03:46 +00:00
|
|
|
|
2014-02-15 03:55:02 +00:00
|
|
|
| Macro macro
|
2013-07-22 11:03:46 +00:00
|
|
|
*/
|
2014-02-15 03:55:02 +00:00
|
|
|
enum class expr_kind { Var, Sort, Constant, Meta, Local, App, Pair, Fst, Snd, Lambda, Pi, Sigma, Let, Macro };
|
2013-07-22 11:03:46 +00:00
|
|
|
class expr_cell {
|
|
|
|
protected:
|
2013-07-24 08:16:35 +00:00
|
|
|
unsigned short m_kind;
|
2013-12-21 21:59:45 +00:00
|
|
|
// The bits of the following field mean:
|
|
|
|
// 0 - term is maximally shared
|
|
|
|
// 1 - term is closed
|
|
|
|
// 2 - term contains metavariables
|
|
|
|
// 3-4 - term is an arrow (0 - not initialized, 1 - is arrow, 2 - is not arrow)
|
2013-12-09 22:56:48 +00:00
|
|
|
atomic_ushort m_flags;
|
2014-01-20 20:28:37 +00:00
|
|
|
unsigned m_hash; // hash based on the structure of the expression (this is a good hash for structural equality)
|
2013-11-14 10:31:54 +00:00
|
|
|
unsigned m_hash_alloc; // hash based on 'time' of allocation (this is a good hash for pointer-based equality)
|
2013-07-22 11:03:46 +00:00
|
|
|
MK_LEAN_RC(); // Declare m_rc counter
|
|
|
|
void dealloc();
|
2013-07-23 18:31:31 +00:00
|
|
|
|
2013-07-24 08:16:35 +00:00
|
|
|
bool max_shared() const { return (m_flags & 1) != 0; }
|
|
|
|
void set_max_shared() { m_flags |= 1; }
|
2013-07-24 07:45:38 +00:00
|
|
|
friend class max_sharing_fn;
|
2013-07-23 18:31:31 +00:00
|
|
|
|
2013-07-24 08:16:35 +00:00
|
|
|
bool is_closed() const { return (m_flags & 2) != 0; }
|
|
|
|
void set_closed() { m_flags |= 2; }
|
2013-12-21 21:59:45 +00:00
|
|
|
|
|
|
|
optional<bool> is_arrow() const;
|
|
|
|
void set_is_arrow(bool flag);
|
|
|
|
friend bool is_arrow(expr const & e);
|
|
|
|
|
2013-07-24 07:45:38 +00:00
|
|
|
friend class has_free_var_fn;
|
2013-11-19 02:41:08 +00:00
|
|
|
static void dec_ref(expr & c, buffer<expr_cell*> & todelete);
|
2013-12-08 07:21:07 +00:00
|
|
|
static void dec_ref(optional<expr> & c, buffer<expr_cell*> & todelete);
|
2013-07-22 11:03:46 +00:00
|
|
|
public:
|
2013-09-13 01:25:38 +00:00
|
|
|
expr_cell(expr_kind k, unsigned h, bool has_mv);
|
2013-07-23 15:59:39 +00:00
|
|
|
expr_kind kind() const { return static_cast<expr_kind>(m_kind); }
|
2013-07-22 11:03:46 +00:00
|
|
|
unsigned hash() const { return m_hash; }
|
2013-11-14 10:31:54 +00:00
|
|
|
unsigned hash_alloc() const { return m_hash_alloc; }
|
2013-09-13 01:25:38 +00:00
|
|
|
bool has_metavar() const { return (m_flags & 4) != 0; }
|
2013-07-22 11:03:46 +00:00
|
|
|
};
|
2014-02-15 03:55:02 +00:00
|
|
|
|
|
|
|
class macro;
|
|
|
|
|
2013-07-22 11:03:46 +00:00
|
|
|
/**
|
|
|
|
\brief Exprs for encoding formulas/expressions, types and proofs.
|
|
|
|
*/
|
|
|
|
class expr {
|
|
|
|
private:
|
|
|
|
expr_cell * m_ptr;
|
2013-12-08 18:17:29 +00:00
|
|
|
explicit expr(expr_cell * ptr):m_ptr(ptr) { if (m_ptr) m_ptr->inc_ref(); }
|
2013-11-19 02:41:08 +00:00
|
|
|
friend class expr_cell;
|
|
|
|
expr_cell * steal_ptr() { expr_cell * r = m_ptr; m_ptr = nullptr; return r; }
|
2013-12-08 18:17:29 +00:00
|
|
|
friend class optional<expr>;
|
2013-07-22 11:03:46 +00:00
|
|
|
public:
|
2013-12-08 22:45:18 +00:00
|
|
|
/**
|
|
|
|
\brief The default constructor creates a reference to a "dummy"
|
|
|
|
expression. The actual "dummy" expression is not relevant, and
|
|
|
|
no procedure should rely on the kind of expression used.
|
|
|
|
|
|
|
|
We have a default constructor because some collections only work
|
|
|
|
with types that have a default constructor.
|
|
|
|
*/
|
2013-12-08 07:21:07 +00:00
|
|
|
expr();
|
2013-07-22 11:03:46 +00:00
|
|
|
expr(expr const & s):m_ptr(s.m_ptr) { if (m_ptr) m_ptr->inc_ref(); }
|
2013-08-01 20:57:43 +00:00
|
|
|
expr(expr && s):m_ptr(s.m_ptr) { s.m_ptr = nullptr; }
|
2013-07-22 11:03:46 +00:00
|
|
|
~expr() { if (m_ptr) m_ptr->dec_ref(); }
|
|
|
|
|
|
|
|
friend void swap(expr & a, expr & b) { std::swap(a.m_ptr, b.m_ptr); }
|
|
|
|
|
2013-12-13 23:00:30 +00:00
|
|
|
expr & operator=(expr const & s) { LEAN_COPY_REF(s); }
|
|
|
|
expr & operator=(expr && s) { LEAN_MOVE_REF(s); }
|
2013-07-22 11:03:46 +00:00
|
|
|
|
|
|
|
expr_kind kind() const { return m_ptr->kind(); }
|
2013-07-30 08:39:29 +00:00
|
|
|
unsigned hash() const { return m_ptr ? m_ptr->hash() : 23; }
|
2013-11-14 10:31:54 +00:00
|
|
|
unsigned hash_alloc() const { return m_ptr ? m_ptr->hash_alloc() : 23; }
|
2013-09-13 01:25:38 +00:00
|
|
|
bool has_metavar() const { return m_ptr->has_metavar(); }
|
2013-07-22 11:03:46 +00:00
|
|
|
|
|
|
|
expr_cell * raw() const { return m_ptr; }
|
|
|
|
|
2013-08-06 18:27:14 +00:00
|
|
|
friend expr mk_var(unsigned idx);
|
2014-02-15 03:55:02 +00:00
|
|
|
friend expr mk_sort(level const & l);
|
2014-02-16 17:53:55 +00:00
|
|
|
friend expr mk_constant(name const & n, levels const & ls);
|
2014-02-17 23:21:48 +00:00
|
|
|
friend expr mk_mlocal(bool is_meta, name const & n, expr const & t);
|
2014-02-15 03:55:02 +00:00
|
|
|
friend expr mk_app(expr const & f, expr const & a);
|
2014-02-04 00:52:49 +00:00
|
|
|
friend expr mk_pair(expr const & f, expr const & s, expr const & t);
|
2014-02-17 23:21:48 +00:00
|
|
|
friend expr mk_proj(bool fst, expr const & p);
|
|
|
|
friend expr mk_binder(expr_kind k, name const & n, expr const & t, expr const & e);
|
2013-12-08 07:21:07 +00:00
|
|
|
friend expr mk_let(name const & n, optional<expr> const & t, expr const & v, expr const & e);
|
2014-02-15 03:55:02 +00:00
|
|
|
friend expr mk_macro(macro * m);
|
2013-07-22 11:03:46 +00:00
|
|
|
|
2013-08-04 16:41:49 +00:00
|
|
|
friend bool is_eqp(expr const & a, expr const & b) { return a.m_ptr == b.m_ptr; }
|
2013-07-23 18:56:15 +00:00
|
|
|
// Overloaded operator() can be used to create applications
|
|
|
|
expr operator()(expr const & a1) const;
|
|
|
|
expr operator()(expr const & a1, expr const & a2) const;
|
|
|
|
expr operator()(expr const & a1, expr const & a2, expr const & a3) const;
|
|
|
|
expr operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4) const;
|
2013-08-06 18:27:14 +00:00
|
|
|
expr operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4, expr const & a5) const;
|
|
|
|
expr operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4, expr const & a5, expr const & a6) const;
|
2014-02-15 03:55:02 +00:00
|
|
|
expr operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4, expr const & a5, expr const & a6,
|
|
|
|
expr const & a7) const;
|
|
|
|
expr operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4, expr const & a5, expr const & a6,
|
|
|
|
expr const & a7, expr const & a8) const;
|
2013-07-22 11:03:46 +00:00
|
|
|
};
|
|
|
|
|
2013-12-08 18:17:29 +00:00
|
|
|
// =======================================
|
|
|
|
// Structural equality
|
|
|
|
bool operator==(expr const & a, expr const & b);
|
|
|
|
inline bool operator!=(expr const & a, expr const & b) { return !operator==(a, b); }
|
|
|
|
// =======================================
|
|
|
|
|
|
|
|
SPECIALIZE_OPTIONAL_FOR_SMART_PTR(expr)
|
|
|
|
|
2013-12-08 18:34:38 +00:00
|
|
|
inline optional<expr> none_expr() { return optional<expr>(); }
|
|
|
|
inline optional<expr> some_expr(expr const & e) { return optional<expr>(e); }
|
|
|
|
inline optional<expr> some_expr(expr && e) { return optional<expr>(std::forward<expr>(e)); }
|
|
|
|
|
2013-12-08 18:17:29 +00:00
|
|
|
inline bool is_eqp(optional<expr> const & a, optional<expr> const & b) {
|
|
|
|
return static_cast<bool>(a) == static_cast<bool>(b) && (!a || is_eqp(*a, *b));
|
|
|
|
}
|
|
|
|
|
2014-02-15 03:55:02 +00:00
|
|
|
/** \brief Bounded variables. They are encoded using de Bruijn's indices. */
|
2013-07-22 11:03:46 +00:00
|
|
|
class expr_var : public expr_cell {
|
|
|
|
unsigned m_vidx; // de Bruijn index
|
|
|
|
public:
|
|
|
|
expr_var(unsigned idx);
|
|
|
|
unsigned get_vidx() const { return m_vidx; }
|
|
|
|
};
|
2014-02-15 03:55:02 +00:00
|
|
|
|
|
|
|
/** \brief (parametric) Constants. */
|
2013-07-22 11:03:46 +00:00
|
|
|
class expr_const : public expr_cell {
|
2014-02-16 17:53:55 +00:00
|
|
|
name m_name;
|
|
|
|
levels m_levels;
|
2013-07-22 11:03:46 +00:00
|
|
|
public:
|
2014-02-16 17:53:55 +00:00
|
|
|
expr_const(name const & n, levels const & ls);
|
2013-07-22 11:03:46 +00:00
|
|
|
name const & get_name() const { return m_name; }
|
2014-02-16 17:53:55 +00:00
|
|
|
levels const & get_level_params() const { return m_levels; }
|
2014-02-15 03:55:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/** \brief Metavariables and local constants */
|
2014-02-16 17:53:55 +00:00
|
|
|
class expr_mlocal : public expr_cell {
|
2014-02-15 03:55:02 +00:00
|
|
|
name m_name;
|
|
|
|
expr m_type;
|
2014-02-16 17:53:55 +00:00
|
|
|
friend expr_cell;
|
|
|
|
void dealloc(buffer<expr_cell*> & todelete);
|
2014-02-15 03:55:02 +00:00
|
|
|
public:
|
2014-02-16 17:53:55 +00:00
|
|
|
expr_mlocal(bool is_meta, name const & n, expr const & t);
|
2014-02-15 03:55:02 +00:00
|
|
|
name const & get_name() const { return m_name; }
|
|
|
|
expr const & get_type() const { return m_type; }
|
2013-07-22 11:03:46 +00:00
|
|
|
};
|
2014-02-15 03:55:02 +00:00
|
|
|
|
|
|
|
/** \brief Composite expressions */
|
|
|
|
class expr_composite : public expr_cell {
|
2014-01-21 01:40:44 +00:00
|
|
|
unsigned m_depth;
|
2014-02-15 03:55:02 +00:00
|
|
|
friend unsigned get_depth(expr const & e);
|
|
|
|
public:
|
|
|
|
expr_composite(expr_kind k, unsigned h, bool has_mv, unsigned d);
|
|
|
|
};
|
|
|
|
|
|
|
|
/** \brief Applications */
|
|
|
|
class expr_app : public expr_composite {
|
|
|
|
expr m_fn;
|
|
|
|
expr m_arg;
|
2013-11-19 02:41:08 +00:00
|
|
|
friend expr_cell;
|
|
|
|
void dealloc(buffer<expr_cell*> & todelete);
|
2013-07-22 11:03:46 +00:00
|
|
|
public:
|
2014-02-15 03:55:02 +00:00
|
|
|
expr_app(expr const & fn, expr const & arg);
|
|
|
|
expr const & get_fn() const { return m_fn; }
|
|
|
|
expr const & get_arg() const { return m_arg; }
|
2013-07-22 11:03:46 +00:00
|
|
|
};
|
2014-02-15 03:55:02 +00:00
|
|
|
|
2014-02-04 00:52:49 +00:00
|
|
|
/** \brief dependent pairs */
|
2014-02-15 03:55:02 +00:00
|
|
|
class expr_dep_pair : public expr_composite {
|
2014-02-04 00:52:49 +00:00
|
|
|
expr m_first;
|
|
|
|
expr m_second;
|
|
|
|
expr m_type;
|
|
|
|
friend expr mk_pair(expr const & f, expr const & s, expr const & t);
|
2014-02-16 17:53:55 +00:00
|
|
|
friend expr_cell;
|
2014-02-04 00:52:49 +00:00
|
|
|
void dealloc(buffer<expr_cell*> & todelete);
|
|
|
|
public:
|
|
|
|
expr_dep_pair(expr const & f, expr const & s, expr const & t);
|
|
|
|
expr const & get_first() const { return m_first; }
|
|
|
|
expr const & get_second() const { return m_second; }
|
|
|
|
expr const & get_type() const { return m_type; }
|
|
|
|
};
|
2014-02-15 03:55:02 +00:00
|
|
|
|
2014-02-04 00:52:49 +00:00
|
|
|
/** \brief dependent pair projection */
|
2014-02-15 03:55:02 +00:00
|
|
|
class expr_proj : public expr_composite {
|
2014-02-04 00:52:49 +00:00
|
|
|
expr m_expr;
|
|
|
|
friend expr_cell;
|
|
|
|
friend expr mk_proj(unsigned idx, expr const & t);
|
|
|
|
void dealloc(buffer<expr_cell*> & todelete);
|
|
|
|
public:
|
|
|
|
expr_proj(bool first, expr const & e);
|
|
|
|
expr const & get_arg() const { return m_expr; }
|
|
|
|
};
|
2014-02-15 03:55:02 +00:00
|
|
|
|
|
|
|
/** \brief Super class for lambda, pi and sigma */
|
|
|
|
class expr_binder : public expr_composite {
|
2013-07-22 11:03:46 +00:00
|
|
|
name m_name;
|
2013-08-03 18:31:42 +00:00
|
|
|
expr m_domain;
|
2013-07-24 04:49:19 +00:00
|
|
|
expr m_body;
|
2013-11-19 02:41:08 +00:00
|
|
|
friend class expr_cell;
|
|
|
|
void dealloc(buffer<expr_cell*> & todelete);
|
2013-07-22 11:03:46 +00:00
|
|
|
public:
|
2014-02-15 03:55:02 +00:00
|
|
|
expr_binder(expr_kind k, name const & n, expr const & t, expr const & e);
|
2013-08-03 18:31:42 +00:00
|
|
|
name const & get_name() const { return m_name; }
|
|
|
|
expr const & get_domain() const { return m_domain; }
|
|
|
|
expr const & get_body() const { return m_body; }
|
2013-07-22 11:03:46 +00:00
|
|
|
};
|
2014-02-15 03:55:02 +00:00
|
|
|
|
2013-08-04 16:37:52 +00:00
|
|
|
/** \brief Let expressions */
|
2014-02-15 03:55:02 +00:00
|
|
|
class expr_let : public expr_composite {
|
2013-12-08 07:21:07 +00:00
|
|
|
name m_name;
|
|
|
|
optional<expr> m_type;
|
|
|
|
expr m_value;
|
|
|
|
expr m_body;
|
2013-11-19 02:41:08 +00:00
|
|
|
friend class expr_cell;
|
|
|
|
void dealloc(buffer<expr_cell*> & todelete);
|
2013-08-04 16:37:52 +00:00
|
|
|
public:
|
2013-12-08 07:21:07 +00:00
|
|
|
expr_let(name const & n, optional<expr> const & t, expr const & v, expr const & b);
|
2013-08-04 16:37:52 +00:00
|
|
|
~expr_let();
|
2014-01-20 20:28:37 +00:00
|
|
|
name const & get_name() const { return m_name; }
|
2013-12-08 07:21:07 +00:00
|
|
|
optional<expr> const & get_type() const { return m_type; }
|
2014-01-20 20:28:37 +00:00
|
|
|
expr const & get_value() const { return m_value; }
|
|
|
|
expr const & get_body() const { return m_body; }
|
2013-08-04 16:37:52 +00:00
|
|
|
};
|
2014-02-15 03:55:02 +00:00
|
|
|
|
|
|
|
/** \brief Sort */
|
|
|
|
class expr_sort : public expr_cell {
|
2013-07-30 02:44:26 +00:00
|
|
|
level m_level;
|
2013-07-22 11:03:46 +00:00
|
|
|
public:
|
2014-02-15 03:55:02 +00:00
|
|
|
expr_sort(level const & l);
|
|
|
|
~expr_sort();
|
2013-07-30 02:44:26 +00:00
|
|
|
level const & get_level() const { return m_level; }
|
2013-07-22 11:03:46 +00:00
|
|
|
};
|
2014-02-15 03:55:02 +00:00
|
|
|
|
|
|
|
class formatter;
|
|
|
|
|
|
|
|
/** \brief Base class for macro attachments */
|
|
|
|
class macro {
|
2013-08-03 23:09:21 +00:00
|
|
|
void dealloc() { delete this; }
|
|
|
|
MK_LEAN_RC();
|
2013-09-24 19:16:32 +00:00
|
|
|
protected:
|
|
|
|
/**
|
2014-02-15 03:55:02 +00:00
|
|
|
\brief Auxiliary method used for implementing a total order on macro
|
2013-09-24 19:16:32 +00:00
|
|
|
attachments. It is invoked by operator<, and it is only invoked when
|
|
|
|
<tt>get_name() == other.get_name()</tt>
|
|
|
|
*/
|
2014-02-15 03:55:02 +00:00
|
|
|
virtual bool lt(macro const &) const { return false; }
|
2013-07-22 11:03:46 +00:00
|
|
|
public:
|
2014-02-15 03:55:02 +00:00
|
|
|
macro():m_rc(0) {}
|
|
|
|
virtual ~macro() {}
|
2013-09-04 06:15:37 +00:00
|
|
|
virtual name get_name() const = 0;
|
2014-02-15 03:55:02 +00:00
|
|
|
virtual expr get_type(buffer<expr> const & arg_types) const = 0;
|
|
|
|
virtual expr expand1(buffer<expr> const & args) const = 0;
|
|
|
|
virtual expr expand(buffer<expr> const & args) const = 0;
|
2013-11-27 03:15:49 +00:00
|
|
|
virtual int push_lua(lua_State * L) const;
|
2014-02-15 03:55:02 +00:00
|
|
|
virtual bool operator==(macro const & other) const;
|
|
|
|
bool operator<(macro const & other) const;
|
|
|
|
virtual void display(std::ostream & out) const;
|
|
|
|
virtual format pp(formatter const & fmt, options const & opts) const;
|
|
|
|
virtual bool is_atomic_pp(bool unicode, bool coercion) const;
|
2013-09-04 06:15:37 +00:00
|
|
|
virtual unsigned hash() const;
|
2013-12-28 09:16:50 +00:00
|
|
|
virtual void write(serializer & s) const = 0;
|
2013-12-30 20:19:00 +00:00
|
|
|
typedef std::function<expr(deserializer&)> reader;
|
2013-12-28 09:16:50 +00:00
|
|
|
static void register_deserializer(std::string const & k, reader rd);
|
2013-12-30 04:47:14 +00:00
|
|
|
struct register_deserializer_fn {
|
2014-02-15 03:55:02 +00:00
|
|
|
register_deserializer_fn(std::string const & k, macro::reader rd) { macro::register_deserializer(k, rd); }
|
2013-12-30 04:47:14 +00:00
|
|
|
};
|
2013-12-28 09:16:50 +00:00
|
|
|
};
|
|
|
|
|
2014-02-15 03:55:02 +00:00
|
|
|
/** \brief Macro attachments */
|
|
|
|
class expr_macro : public expr_cell {
|
|
|
|
macro * m_macro;
|
2013-08-03 23:09:21 +00:00
|
|
|
friend expr copy(expr const & a);
|
|
|
|
public:
|
2014-02-15 03:55:02 +00:00
|
|
|
expr_macro(macro * v);
|
|
|
|
~expr_macro();
|
2013-09-13 01:25:38 +00:00
|
|
|
|
2014-02-15 03:55:02 +00:00
|
|
|
macro const & get_macro() const { return *m_macro; }
|
2013-09-13 01:25:38 +00:00
|
|
|
};
|
2013-07-22 11:03:46 +00:00
|
|
|
|
|
|
|
// =======================================
|
|
|
|
// Testers
|
|
|
|
inline bool is_var(expr_cell * e) { return e->kind() == expr_kind::Var; }
|
|
|
|
inline bool is_constant(expr_cell * e) { return e->kind() == expr_kind::Constant; }
|
2014-02-15 03:55:02 +00:00
|
|
|
inline bool is_local(expr_cell * e) { return e->kind() == expr_kind::Local; }
|
|
|
|
inline bool is_metavar(expr_cell * e) { return e->kind() == expr_kind::Meta; }
|
|
|
|
inline bool is_macro(expr_cell * e) { return e->kind() == expr_kind::Macro; }
|
2014-02-08 00:04:44 +00:00
|
|
|
inline bool is_dep_pair(expr_cell * e) { return e->kind() == expr_kind::Pair; }
|
2014-02-15 03:55:02 +00:00
|
|
|
inline bool is_fst(expr_cell * e) { return e->kind() == expr_kind::Fst; }
|
|
|
|
inline bool is_snd(expr_cell * e) { return e->kind() == expr_kind::Snd; }
|
2013-07-22 11:03:46 +00:00
|
|
|
inline bool is_app(expr_cell * e) { return e->kind() == expr_kind::App; }
|
|
|
|
inline bool is_lambda(expr_cell * e) { return e->kind() == expr_kind::Lambda; }
|
|
|
|
inline bool is_pi(expr_cell * e) { return e->kind() == expr_kind::Pi; }
|
2014-02-04 00:52:49 +00:00
|
|
|
inline bool is_sigma(expr_cell * e) { return e->kind() == expr_kind::Sigma; }
|
2014-02-15 03:55:02 +00:00
|
|
|
inline bool is_sort(expr_cell * e) { return e->kind() == expr_kind::Sort; }
|
2013-08-04 16:37:52 +00:00
|
|
|
inline bool is_let(expr_cell * e) { return e->kind() == expr_kind::Let; }
|
2014-02-15 03:55:02 +00:00
|
|
|
inline bool is_binder(expr_cell * e) { return is_lambda(e) || is_pi(e) || is_sigma(e); }
|
|
|
|
inline bool is_proj(expr_cell * e) { return is_fst(e) || is_snd(e); }
|
2014-02-16 17:53:55 +00:00
|
|
|
inline bool is_mlocal(expr_cell * e) { return is_metavar(e) || is_local(e); }
|
2014-02-15 03:55:02 +00:00
|
|
|
|
|
|
|
inline bool is_var(expr const & e) { return e.kind() == expr_kind::Var; }
|
|
|
|
inline bool is_constant(expr const & e) { return e.kind() == expr_kind::Constant; }
|
|
|
|
inline bool is_local(expr const & e) { return e.kind() == expr_kind::Local; }
|
|
|
|
inline bool is_metavar(expr const & e) { return e.kind() == expr_kind::Meta; }
|
|
|
|
inline bool is_macro(expr const & e) { return e.kind() == expr_kind::Macro; }
|
|
|
|
inline bool is_dep_pair(expr const & e) { return e.kind() == expr_kind::Pair; }
|
|
|
|
inline bool is_fst(expr const & e) { return e.kind() == expr_kind::Fst; }
|
|
|
|
inline bool is_snd(expr const & e) { return e.kind() == expr_kind::Snd; }
|
|
|
|
inline bool is_app(expr const & e) { return e.kind() == expr_kind::App; }
|
|
|
|
inline bool is_lambda(expr const & e) { return e.kind() == expr_kind::Lambda; }
|
|
|
|
inline bool is_pi(expr const & e) { return e.kind() == expr_kind::Pi; }
|
|
|
|
inline bool is_sigma(expr const & e) { return e.kind() == expr_kind::Sigma; }
|
|
|
|
inline bool is_sort(expr const & e) { return e.kind() == expr_kind::Sort; }
|
|
|
|
inline bool is_let(expr const & e) { return e.kind() == expr_kind::Let; }
|
|
|
|
inline bool is_binder(expr const & e) { return is_lambda(e) || is_pi(e) || is_sigma(e); }
|
|
|
|
inline bool is_proj(expr const & e) { return is_fst(e) || is_snd(e); }
|
2014-02-16 17:53:55 +00:00
|
|
|
inline bool is_mlocal(expr const & e) { return is_metavar(e) || is_local(e); }
|
2014-02-18 00:10:11 +00:00
|
|
|
|
|
|
|
bool is_atomic(expr const & e);
|
|
|
|
bool is_arrow(expr const & t);
|
|
|
|
bool is_cartesian(expr const & t);
|
2013-07-22 11:03:46 +00:00
|
|
|
// =======================================
|
|
|
|
|
|
|
|
// =======================================
|
|
|
|
// Constructors
|
2013-08-06 18:27:14 +00:00
|
|
|
inline expr mk_var(unsigned idx) { return expr(new expr_var(idx)); }
|
|
|
|
inline expr Var(unsigned idx) { return mk_var(idx); }
|
2014-02-16 17:53:55 +00:00
|
|
|
inline expr mk_constant(name const & n, levels const & ls) { return expr(new expr_const(n, ls)); }
|
|
|
|
inline expr mk_constant(name const & n) { return mk_constant(n, levels()); }
|
2013-08-06 18:27:14 +00:00
|
|
|
inline expr Const(name const & n) { return mk_constant(n); }
|
2014-02-15 03:55:02 +00:00
|
|
|
inline expr mk_macro(macro * m) { return expr(new expr_macro(m)); }
|
2014-02-17 23:21:48 +00:00
|
|
|
inline expr mk_mlocal(bool is_meta, name const & n, expr const & t) { return expr(new expr_mlocal(is_meta, n, t)); }
|
|
|
|
inline expr mk_metavar(name const & n, expr const & t) { return mk_mlocal(true, n, t); }
|
|
|
|
inline expr mk_local(name const & n, expr const & t) { return mk_mlocal(false, n, t); }
|
2014-02-04 00:52:49 +00:00
|
|
|
inline expr mk_pair(expr const & f, expr const & s, expr const & t) { return expr(new expr_dep_pair(f, s, t)); }
|
2014-02-17 23:21:48 +00:00
|
|
|
inline expr mk_proj(bool first, expr const & a) { return expr(new expr_proj(first, a)); }
|
|
|
|
inline expr mk_fst(expr const & a) { return mk_proj(true, a); }
|
|
|
|
inline expr mk_snd(expr const & a) { return mk_proj(false, a); }
|
2014-02-15 03:55:02 +00:00
|
|
|
inline expr mk_app(expr const & f, expr const & a) { return expr(new expr_app(f, a)); }
|
2013-08-06 18:27:14 +00:00
|
|
|
expr mk_app(unsigned num_args, expr const * args);
|
|
|
|
inline expr mk_app(std::initializer_list<expr> const & l) { return mk_app(l.size(), l.begin()); }
|
2013-10-26 21:46:12 +00:00
|
|
|
template<typename T> expr mk_app(T const & args) { return mk_app(args.size(), args.data()); }
|
2014-02-17 23:21:48 +00:00
|
|
|
inline expr mk_binder(expr_kind k, name const & n, expr const & t, expr const & e) { return expr(new expr_binder(k, n, t, e)); }
|
|
|
|
inline expr mk_lambda(name const & n, expr const & t, expr const & e) { return mk_binder(expr_kind::Lambda, n, t, e); }
|
|
|
|
inline expr mk_pi(name const & n, expr const & t, expr const & e) { return mk_binder(expr_kind::Pi, n, t, e); }
|
|
|
|
inline expr mk_sigma(name const & n, expr const & t, expr const & e) { return mk_binder(expr_kind::Sigma, n, t, e); }
|
2014-02-15 03:55:02 +00:00
|
|
|
inline expr mk_let(name const & n, optional<expr> const & t, expr const & v, expr const & e) {
|
|
|
|
return expr(new expr_let(n, t, v, e));
|
|
|
|
}
|
2013-12-08 18:34:38 +00:00
|
|
|
inline expr mk_let(name const & n, expr const & t, expr const & v, expr const & e) { return mk_let(n, some_expr(t), v, e); }
|
|
|
|
inline expr mk_let(name const & n, expr const & v, expr const & e) { return mk_let(n, none_expr(), v, e); }
|
2014-02-15 03:55:02 +00:00
|
|
|
inline expr mk_sort(level const & l) { return expr(new expr_sort(l)); }
|
2014-02-16 17:53:55 +00:00
|
|
|
|
2014-02-15 03:55:02 +00:00
|
|
|
expr mk_Bool();
|
|
|
|
expr mk_Type();
|
|
|
|
extern expr Type;
|
|
|
|
extern expr Bool;
|
2013-08-06 18:27:14 +00:00
|
|
|
|
2014-02-16 17:53:55 +00:00
|
|
|
bool is_default_var_name(name const & n);
|
|
|
|
expr mk_arrow(expr const & t, expr const & e);
|
|
|
|
expr mk_cartesian_product(expr const & t, expr const & e);
|
|
|
|
inline expr operator>>(expr const & t, expr const & e) { return mk_arrow(t, e); }
|
|
|
|
|
2014-02-15 03:55:02 +00:00
|
|
|
// Auxiliary
|
|
|
|
inline expr mk_app(expr const & e1, expr const & e2, expr const & e3) { return mk_app({e1, e2, e3}); }
|
|
|
|
inline expr mk_app(expr const & e1, expr const & e2, expr const & e3, expr const & e4) { return mk_app({e1, e2, e3, e4}); }
|
|
|
|
inline expr mk_app(expr const & e1, expr const & e2, expr const & e3, expr const & e4, expr const & e5) {
|
|
|
|
return mk_app({e1, e2, e3, e4, e5});
|
|
|
|
}
|
2013-08-06 18:27:14 +00:00
|
|
|
inline expr expr::operator()(expr const & a1) const { return mk_app({*this, a1}); }
|
|
|
|
inline expr expr::operator()(expr const & a1, expr const & a2) const { return mk_app({*this, a1, a2}); }
|
|
|
|
inline expr expr::operator()(expr const & a1, expr const & a2, expr const & a3) const { return mk_app({*this, a1, a2, a3}); }
|
2014-02-15 03:55:02 +00:00
|
|
|
inline expr expr::operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4) const {
|
|
|
|
return mk_app({*this, a1, a2, a3, a4});
|
|
|
|
}
|
|
|
|
inline expr expr::operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4, expr const & a5) const {
|
|
|
|
return mk_app({*this, a1, a2, a3, a4, a5});
|
|
|
|
}
|
|
|
|
inline expr expr::operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4, expr const & a5,
|
|
|
|
expr const & a6) const {
|
|
|
|
return mk_app({*this, a1, a2, a3, a4, a5, a6});
|
|
|
|
}
|
|
|
|
inline expr expr::operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4, expr const & a5,
|
|
|
|
expr const & a6, expr const & a7) const {
|
|
|
|
return mk_app({*this, a1, a2, a3, a4, a5, a6, a7});
|
|
|
|
}
|
|
|
|
inline expr expr::operator()(expr const & a1, expr const & a2, expr const & a3, expr const & a4, expr const & a5,
|
|
|
|
expr const & a6, expr const & a7, expr const & a8) const {
|
|
|
|
return mk_app({*this, a1, a2, a3, a4, a5, a6, a7, a8});
|
|
|
|
}
|
2013-07-22 11:03:46 +00:00
|
|
|
// =======================================
|
|
|
|
|
|
|
|
// =======================================
|
2013-07-23 15:59:39 +00:00
|
|
|
// Casting (these functions are only needed for low-level code)
|
2014-02-15 03:55:02 +00:00
|
|
|
inline expr_var * to_var(expr_cell * e) { lean_assert(is_var(e)); return static_cast<expr_var*>(e); }
|
|
|
|
inline expr_const * to_constant(expr_cell * e) { lean_assert(is_constant(e)); return static_cast<expr_const*>(e); }
|
|
|
|
inline expr_dep_pair * to_pair(expr_cell * e) { lean_assert(is_dep_pair(e)); return static_cast<expr_dep_pair*>(e); }
|
|
|
|
inline expr_proj * to_proj(expr_cell * e) { lean_assert(is_proj(e)); return static_cast<expr_proj*>(e); }
|
|
|
|
inline expr_app * to_app(expr_cell * e) { lean_assert(is_app(e)); return static_cast<expr_app*>(e); }
|
|
|
|
inline expr_binder * to_binder(expr_cell * e) { lean_assert(is_binder(e)); return static_cast<expr_binder*>(e); }
|
|
|
|
inline expr_let * to_let(expr_cell * e) { lean_assert(is_let(e)); return static_cast<expr_let*>(e); }
|
|
|
|
inline expr_sort * to_sort(expr_cell * e) { lean_assert(is_sort(e)); return static_cast<expr_sort*>(e); }
|
2014-02-16 17:53:55 +00:00
|
|
|
inline expr_mlocal * to_mlocal(expr_cell * e) { lean_assert(is_mlocal(e)); return static_cast<expr_mlocal*>(e); }
|
|
|
|
inline expr_mlocal * to_local(expr_cell * e) { lean_assert(is_local(e)); return static_cast<expr_mlocal*>(e); }
|
|
|
|
inline expr_mlocal * to_metavar(expr_cell * e) { lean_assert(is_metavar(e)); return static_cast<expr_mlocal*>(e); }
|
2013-07-22 11:03:46 +00:00
|
|
|
|
|
|
|
inline expr_var * to_var(expr const & e) { return to_var(e.raw()); }
|
|
|
|
inline expr_const * to_constant(expr const & e) { return to_constant(e.raw()); }
|
2014-02-04 00:52:49 +00:00
|
|
|
inline expr_dep_pair * to_pair(expr const & e) { return to_pair(e.raw()); }
|
|
|
|
inline expr_proj * to_proj(expr const & e) { return to_proj(e.raw()); }
|
2013-07-22 11:03:46 +00:00
|
|
|
inline expr_app * to_app(expr const & e) { return to_app(e.raw()); }
|
2014-02-15 03:55:02 +00:00
|
|
|
inline expr_binder * to_binder(expr const & e) { return to_binder(e.raw()); }
|
2013-08-04 16:37:52 +00:00
|
|
|
inline expr_let * to_let(expr const & e) { return to_let(e.raw()); }
|
2014-02-15 03:55:02 +00:00
|
|
|
inline expr_sort * to_sort(expr const & e) { return to_sort(e.raw()); }
|
2014-02-16 17:53:55 +00:00
|
|
|
inline expr_mlocal * to_mlocal(expr const & e) { return to_mlocal(e.raw()); }
|
|
|
|
inline expr_mlocal * to_metavar(expr const & e) { return to_metavar(e.raw()); }
|
|
|
|
inline expr_mlocal * to_local(expr const & e) { return to_local(e.raw()); }
|
2013-07-22 11:03:46 +00:00
|
|
|
// =======================================
|
|
|
|
|
2014-02-15 03:55:02 +00:00
|
|
|
|
2013-07-22 11:03:46 +00:00
|
|
|
// =======================================
|
|
|
|
// Accessors
|
2014-02-16 17:53:55 +00:00
|
|
|
inline unsigned get_rc(expr_cell * e) { return e->get_rc(); }
|
|
|
|
inline bool is_shared(expr_cell * e) { return get_rc(e) > 1; }
|
|
|
|
inline unsigned var_idx(expr_cell * e) { return to_var(e)->get_vidx(); }
|
|
|
|
inline bool is_var(expr_cell * e, unsigned i) { return is_var(e) && var_idx(e) == i; }
|
|
|
|
inline name const & const_name(expr_cell * e) { return to_constant(e)->get_name(); }
|
|
|
|
inline levels const & const_level_params(expr_cell * e) { return to_constant(e)->get_level_params(); }
|
|
|
|
inline expr const & pair_first(expr_cell * e) { return to_pair(e)->get_first(); }
|
|
|
|
inline expr const & pair_second(expr_cell * e) { return to_pair(e)->get_second(); }
|
|
|
|
inline expr const & pair_type(expr_cell * e) { return to_pair(e)->get_type(); }
|
|
|
|
inline expr const & proj_arg(expr_cell * e) { return to_proj(e)->get_arg(); }
|
|
|
|
inline macro const & to_macro(expr_cell * e) {
|
|
|
|
lean_assert(is_macro(e)); return static_cast<expr_macro*>(e)->get_macro(); }
|
|
|
|
inline expr const & app_fn(expr_cell * e) { return to_app(e)->get_fn(); }
|
|
|
|
inline expr const & app_arg(expr_cell * e) { return to_app(e)->get_arg(); }
|
|
|
|
inline name const & binder_name(expr_cell * e) { return to_binder(e)->get_name(); }
|
|
|
|
inline expr const & binder_domain(expr_cell * e) { return to_binder(e)->get_domain(); }
|
|
|
|
inline expr const & binder_body(expr_cell * e) { return to_binder(e)->get_body(); }
|
|
|
|
inline level const & sort_level(expr_cell * e) { return to_sort(e)->get_level(); }
|
|
|
|
inline name const & let_name(expr_cell * e) { return to_let(e)->get_name(); }
|
|
|
|
inline expr const & let_value(expr_cell * e) { return to_let(e)->get_value(); }
|
|
|
|
inline optional<expr> const & let_type(expr_cell * e) { return to_let(e)->get_type(); }
|
|
|
|
inline expr const & let_body(expr_cell * e) { return to_let(e)->get_body(); }
|
|
|
|
inline name const & mlocal_name(expr_cell * e) { return to_mlocal(e)->get_name(); }
|
|
|
|
inline expr const & mlocal_type(expr_cell * e) { return to_mlocal(e)->get_type(); }
|
|
|
|
|
|
|
|
inline unsigned get_rc(expr const & e) { return e.raw()->get_rc(); }
|
|
|
|
inline bool is_shared(expr const & e) { return get_rc(e) > 1; }
|
|
|
|
inline unsigned var_idx(expr const & e) { return to_var(e)->get_vidx(); }
|
|
|
|
inline bool is_var(expr const & e, unsigned i) { return is_var(e) && var_idx(e) == i; }
|
|
|
|
inline name const & const_name(expr const & e) { return to_constant(e)->get_name(); }
|
|
|
|
inline levels const & const_level_params(expr const & e) { return to_constant(e)->get_level_params(); }
|
|
|
|
inline expr const & pair_first(expr const & e) { return to_pair(e)->get_first(); }
|
|
|
|
inline expr const & pair_second(expr const & e) { return to_pair(e)->get_second(); }
|
|
|
|
inline expr const & pair_type(expr const & e) { return to_pair(e)->get_type(); }
|
|
|
|
inline expr const & proj_arg(expr const & e) { return to_proj(e)->get_arg(); }
|
|
|
|
inline macro const & to_macro(expr const & e) { return to_macro(e.raw()); }
|
|
|
|
inline expr const & app_fn(expr const & e) { return to_app(e)->get_fn(); }
|
|
|
|
inline expr const & app_arg(expr const & e) { return to_app(e)->get_arg(); }
|
|
|
|
inline name const & binder_name(expr const & e) { return to_binder(e)->get_name(); }
|
|
|
|
inline expr const & binder_domain(expr const & e) { return to_binder(e)->get_domain(); }
|
|
|
|
inline expr const & binder_body(expr const & e) { return to_binder(e)->get_body(); }
|
|
|
|
inline level const & sort_level(expr const & e) { return to_sort(e)->get_level(); }
|
|
|
|
inline name const & let_name(expr const & e) { return to_let(e)->get_name(); }
|
|
|
|
inline expr const & let_value(expr const & e) { return to_let(e)->get_value(); }
|
|
|
|
inline optional<expr> const & let_type(expr const & e) { return to_let(e)->get_type(); }
|
|
|
|
inline expr const & let_body(expr const & e) { return to_let(e)->get_body(); }
|
|
|
|
inline name const & mlocal_name(expr const & e) { return to_mlocal(e)->get_name(); }
|
|
|
|
inline expr const & mlocal_type(expr const & e) { return to_mlocal(e)->get_type(); }
|
|
|
|
|
|
|
|
inline bool is_constant(expr const & e, name const & n) { return is_constant(e) && const_name(e) == n; }
|
2013-09-13 01:25:38 +00:00
|
|
|
inline bool has_metavar(expr const & e) { return e.has_metavar(); }
|
2014-02-16 17:53:55 +00:00
|
|
|
inline bool has_metavar(optional<expr> const & e) { return e && has_metavar(*e); }
|
|
|
|
unsigned get_depth(expr const & e);
|
|
|
|
inline unsigned get_depth(optional<expr> const & e) { return e ? get_depth(*e) : 0; }
|
2013-07-22 11:03:46 +00:00
|
|
|
// =======================================
|
|
|
|
|
2014-02-16 17:53:55 +00:00
|
|
|
|
2013-07-23 17:16:47 +00:00
|
|
|
// =======================================
|
|
|
|
// Expression+Offset
|
|
|
|
typedef std::pair<expr, unsigned> expr_offset;
|
|
|
|
typedef std::pair<expr_cell*, unsigned> expr_cell_offset;
|
|
|
|
// =======================================
|
|
|
|
|
2013-07-23 17:09:04 +00:00
|
|
|
// =======================================
|
2013-07-24 07:45:38 +00:00
|
|
|
// Auxiliary functionals
|
2013-07-26 18:43:53 +00:00
|
|
|
/** \brief Functional object for hashing kernel expressions. */
|
2013-07-23 17:09:04 +00:00
|
|
|
struct expr_hash { unsigned operator()(expr const & e) const { return e.hash(); } };
|
2013-11-14 10:31:54 +00:00
|
|
|
/**
|
|
|
|
\brief Functional object for hashing (based on allocation time) kernel expressions.
|
|
|
|
|
|
|
|
This hash is compatible with pointer equality.
|
|
|
|
\warning This hash is incompatible with structural equality (i.e., std::equal_to<expr>)
|
|
|
|
*/
|
|
|
|
struct expr_hash_alloc { unsigned operator()(expr const & e) const { return e.hash_alloc(); } };
|
2013-07-26 18:43:53 +00:00
|
|
|
/** \brief Functional object for testing pointer equality between kernel expressions. */
|
2013-08-04 16:41:49 +00:00
|
|
|
struct expr_eqp { bool operator()(expr const & e1, expr const & e2) const { return is_eqp(e1, e2); } };
|
2013-07-26 18:43:53 +00:00
|
|
|
/** \brief Functional object for hashing kernel expression cells. */
|
2013-11-14 10:31:54 +00:00
|
|
|
struct expr_cell_hash { unsigned operator()(expr_cell * e) const { return e->hash_alloc(); } };
|
2013-07-26 18:43:53 +00:00
|
|
|
/** \brief Functional object for testing pointer equality between kernel cell expressions. */
|
2013-07-23 17:09:04 +00:00
|
|
|
struct expr_cell_eqp { bool operator()(expr_cell * e1, expr_cell * e2) const { return e1 == e2; } };
|
2013-09-13 19:49:03 +00:00
|
|
|
/** \brief Functional object for hashing a pair (n, k) where n is a kernel expressions, and k is an offset. */
|
2013-11-14 10:31:54 +00:00
|
|
|
struct expr_offset_hash { unsigned operator()(expr_offset const & p) const { return hash(p.first.hash_alloc(), p.second); } };
|
2013-07-26 18:43:53 +00:00
|
|
|
/** \brief Functional object for comparing pairs (expression, offset). */
|
2013-08-04 16:41:49 +00:00
|
|
|
struct expr_offset_eqp { unsigned operator()(expr_offset const & p1, expr_offset const & p2) const { return is_eqp(p1.first, p2.first) && p1.second == p2.second; } };
|
2013-09-13 19:49:03 +00:00
|
|
|
/** \brief Functional object for hashing a pair (n, k) where n is a kernel cell expressions, and k is an offset. */
|
2013-11-14 10:31:54 +00:00
|
|
|
struct expr_cell_offset_hash { unsigned operator()(expr_cell_offset const & p) const { return hash(p.first->hash_alloc(), p.second); } };
|
2013-07-26 18:43:53 +00:00
|
|
|
/** \brief Functional object for comparing pairs (expression cell, offset). */
|
2013-07-23 17:16:47 +00:00
|
|
|
struct expr_cell_offset_eqp { unsigned operator()(expr_cell_offset const & p1, expr_cell_offset const & p2) const { return p1 == p2; } };
|
2013-07-23 17:09:04 +00:00
|
|
|
// =======================================
|
2013-07-22 11:03:46 +00:00
|
|
|
|
2013-07-24 17:14:22 +00:00
|
|
|
/**
|
|
|
|
\brief Return a shallow copy of \c e
|
|
|
|
*/
|
|
|
|
expr copy(expr const & e);
|
2014-02-16 17:53:55 +00:00
|
|
|
|
2013-07-30 04:28:22 +00:00
|
|
|
// =======================================
|
|
|
|
// Update
|
2014-02-16 17:53:55 +00:00
|
|
|
expr update_app(expr const & e, expr const & new_fn, expr const & new_arg);
|
|
|
|
expr update_proj(expr const & e, expr const & new_arg);
|
|
|
|
expr update_pair(expr const & e, expr const & new_first, expr const & new_second, expr const & new_type);
|
|
|
|
expr update_binder(expr const & e, expr const & new_domain, expr const & new_body);
|
|
|
|
expr update_let(expr const & e, optional<expr> const & new_type, expr const & new_val, expr const & new_body);
|
|
|
|
expr update_mlocal(expr const & e, expr const & new_type);
|
2013-07-30 04:28:22 +00:00
|
|
|
// =======================================
|
2013-09-26 00:45:13 +00:00
|
|
|
|
2013-12-28 09:16:50 +00:00
|
|
|
// =======================================
|
|
|
|
// Serializer/Deserializer
|
|
|
|
serializer & operator<<(serializer & s, expr const & e);
|
|
|
|
expr read_expr(deserializer & d);
|
|
|
|
inline deserializer & operator>>(deserializer & d, expr & e) { e = read_expr(d); return d; }
|
|
|
|
// =======================================
|
|
|
|
|
2013-09-26 00:45:13 +00:00
|
|
|
std::ostream & operator<<(std::ostream & out, expr const & e);
|
2013-07-22 11:03:46 +00:00
|
|
|
}
|