2013-09-13 01:25:38 +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 "util/pair.h"
|
|
|
|
#include "util/pvector.h"
|
|
|
|
#include "kernel/expr.h"
|
2013-09-16 02:37:59 +00:00
|
|
|
#include "kernel/context.h"
|
2013-09-13 01:25:38 +00:00
|
|
|
|
|
|
|
namespace lean {
|
|
|
|
/**
|
|
|
|
\brief Set of unification problems that need to be solved.
|
|
|
|
It store two kinds of problems:
|
2013-09-16 02:37:59 +00:00
|
|
|
1. <tt>ctx |- lhs == rhs</tt>
|
|
|
|
2. <tt>ctx |- typeof(n) == t</tt>
|
2013-09-17 14:15:47 +00:00
|
|
|
3. <tt>ctx |- t1 is_convertible_to t2</tt>
|
2013-09-13 01:25:38 +00:00
|
|
|
*/
|
|
|
|
class unification_problems {
|
|
|
|
public:
|
2013-09-16 02:37:59 +00:00
|
|
|
virtual ~unification_problems() {}
|
2013-09-13 01:25:38 +00:00
|
|
|
/**
|
2013-09-16 02:37:59 +00:00
|
|
|
\brief Add a new unification problem of the form <tt>ctx |- lhs == rhs</tt>
|
2013-09-13 01:25:38 +00:00
|
|
|
*/
|
2013-09-16 02:37:59 +00:00
|
|
|
virtual void add_eq(context const & ctx, expr const & lhs, expr const & rhs) = 0;
|
2013-09-13 01:25:38 +00:00
|
|
|
/**
|
2013-09-16 02:37:59 +00:00
|
|
|
\brief Add a new unification problem of the form <tt>ctx |- typeof(n) == t</tt>
|
2013-09-13 01:25:38 +00:00
|
|
|
*/
|
2013-09-16 02:37:59 +00:00
|
|
|
virtual void add_type_of_eq(context const & ctx, expr const & n, expr const & t) = 0;
|
2013-09-17 14:15:47 +00:00
|
|
|
/**
|
|
|
|
\brief Add a new problem of the form <tt>ctx |- t1 is_convertible_to t2</tt>
|
|
|
|
|
|
|
|
\remark <tt>ctx |- t1 == t2</tt> implies <tt>ctx |- t1 is_convertible_to t2</tt>
|
|
|
|
*/
|
|
|
|
virtual void add_is_convertible(context const & ctx, expr const & t1, expr const & t2) = 0;
|
2013-09-13 01:25:38 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
\brief Metavariable environment. It is essentially a mapping
|
|
|
|
from metavariables to assignments and types.
|
|
|
|
*/
|
|
|
|
class metavar_env {
|
2013-09-16 02:37:59 +00:00
|
|
|
struct data {
|
|
|
|
expr m_subst;
|
|
|
|
expr m_type;
|
|
|
|
context m_ctx;
|
2013-09-19 03:46:00 +00:00
|
|
|
data(expr const & t, context const & ctx):m_type(t), m_ctx(ctx) {}
|
2013-09-16 02:37:59 +00:00
|
|
|
data(expr const & s, expr const & t, context const & ctx):m_subst(s), m_type(t), m_ctx(ctx) {}
|
|
|
|
};
|
|
|
|
pvector<data> m_env;
|
2013-09-16 02:50:48 +00:00
|
|
|
unsigned m_timestamp;
|
|
|
|
void inc_timestamp();
|
2013-09-13 01:25:38 +00:00
|
|
|
public:
|
2013-09-16 02:50:48 +00:00
|
|
|
metavar_env();
|
|
|
|
|
|
|
|
/**
|
|
|
|
\brief The timestamp is increased whenever the environment is updated by
|
|
|
|
\c mk_metavar or \c assign.
|
|
|
|
*/
|
|
|
|
unsigned get_timestamp() const { return m_timestamp; }
|
|
|
|
|
2013-09-19 03:46:00 +00:00
|
|
|
/**
|
|
|
|
\brief Return the number of metavariables in this metavar_env.
|
|
|
|
*/
|
|
|
|
unsigned size() const { return m_env.size(); }
|
|
|
|
|
2013-09-13 01:25:38 +00:00
|
|
|
/**
|
|
|
|
\brief Create new metavariable in this environment.
|
|
|
|
*/
|
2013-09-16 02:37:59 +00:00
|
|
|
expr mk_metavar(context const & ctx = context());
|
2013-09-13 01:25:38 +00:00
|
|
|
|
2013-09-19 03:46:00 +00:00
|
|
|
/**
|
|
|
|
\brief Create a new metavariable with the given type and context.
|
|
|
|
*/
|
|
|
|
expr mk_metavar(expr const & type, context const & ctx = context());
|
|
|
|
|
2013-09-13 01:25:38 +00:00
|
|
|
/**
|
|
|
|
\brief Return true if this environment contains a metavariable
|
|
|
|
with id \c midx. That is, it has an entry of the form
|
|
|
|
<tt>midx -> (s, t)</tt>.
|
|
|
|
*/
|
|
|
|
bool contains(unsigned midx) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
\brief Return true if the metavariable with id \c midx is assigned in
|
|
|
|
this environment.
|
|
|
|
|
|
|
|
\pre contains(midx)
|
|
|
|
*/
|
|
|
|
bool is_assigned(unsigned midx) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
\brief Return the substitution associated with the metavariable with id \c midx
|
|
|
|
in this environment.
|
|
|
|
If the metavariable is not assigned in this environment, then it returns the null
|
|
|
|
expression.
|
|
|
|
|
|
|
|
\pre contains(midx)
|
|
|
|
*/
|
|
|
|
expr get_subst(unsigned midx) const;
|
|
|
|
|
2013-09-19 03:46:00 +00:00
|
|
|
expr get_subst_core(unsigned midx) const;
|
|
|
|
|
2013-09-13 01:25:38 +00:00
|
|
|
/**
|
|
|
|
\brief Return the type of the metavariable with id \c midx in this environment.
|
|
|
|
|
|
|
|
\remark A new metavariable may be created to represent the type of the input
|
|
|
|
metavariable. When this happens, a new unification problem of the form
|
|
|
|
<tt>typeof(m) = t</tt> is added to \c up, where \c m is the metavariable
|
|
|
|
with id \c midx, and \c t is the result of this method.
|
|
|
|
|
|
|
|
\pre contains(midx)
|
|
|
|
*/
|
|
|
|
expr get_type(unsigned midx, unification_problems & up);
|
|
|
|
|
2013-09-19 03:46:00 +00:00
|
|
|
/**
|
|
|
|
\brief Return type of the metavariable with id \c midx in this environment.
|
|
|
|
If the metavariable is not associated with any type, then return the null expression.
|
|
|
|
*/
|
|
|
|
expr get_type(unsigned midx) const;
|
|
|
|
|
2013-09-13 01:25:38 +00:00
|
|
|
/**
|
|
|
|
\brief Assign the metavariable with id \c midx to the term \c t.
|
|
|
|
|
|
|
|
\pre !is_assigned(midx)
|
|
|
|
*/
|
|
|
|
void assign(unsigned midx, expr const & t);
|
|
|
|
|
2013-09-17 18:09:59 +00:00
|
|
|
/**
|
|
|
|
\brief Return the context associated with a metavariable.
|
|
|
|
*/
|
|
|
|
context const & get_context(unsigned midx) const;
|
|
|
|
|
2013-09-13 01:25:38 +00:00
|
|
|
/**
|
|
|
|
\brief Return true if this environment contains the given metavariable
|
|
|
|
|
|
|
|
\pre is_metavar(m)
|
|
|
|
*/
|
|
|
|
bool contains(expr const & m) const { return contains(metavar_idx(m)); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
\pre contains(m)
|
|
|
|
*/
|
|
|
|
bool is_assigned(expr const & m) const { return is_assigned(metavar_idx(m)); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
\brief Return the substitution associated with the metavariable \c m.
|
|
|
|
If \c m has a context ctx associated with it, then the substitution is
|
|
|
|
'moved' to ctx.
|
|
|
|
|
|
|
|
\pre contains(m)
|
|
|
|
*/
|
|
|
|
expr get_subst(expr const & m) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
\brief Return the type of the given metavariable.
|
|
|
|
If \c m has a context ctx associated with it, then the type is
|
|
|
|
'moved' to ctx.
|
|
|
|
|
|
|
|
\pre contains(m)
|
|
|
|
*/
|
|
|
|
expr get_type(expr const & m, unification_problems & up);
|
|
|
|
|
|
|
|
/**
|
|
|
|
\brief Assign the metavariable \c m to \c t.
|
|
|
|
The metavariable must not have a context associated with it.
|
|
|
|
|
|
|
|
\pre contains(m)
|
|
|
|
\pre !metavar_ctx(m)
|
|
|
|
\pre !is_assigned(m)
|
|
|
|
*/
|
|
|
|
void assign(expr const & m, expr const & t);
|
|
|
|
};
|
|
|
|
|
2013-09-21 07:41:13 +00:00
|
|
|
expr instantiate(expr const & s, meta_ctx const & ctx, metavar_env const & env);
|
|
|
|
|
2013-09-13 01:25:38 +00:00
|
|
|
/**
|
|
|
|
\brief Instantiate the metavariables occurring in \c e with the substitutions
|
|
|
|
provided by \c env.
|
|
|
|
*/
|
|
|
|
expr instantiate_metavars(expr const & e, metavar_env const & env);
|
|
|
|
|
2013-09-16 17:58:56 +00:00
|
|
|
/**
|
|
|
|
\brief Extend the context \c ctx with the entry <tt>lift:s:n</tt>
|
|
|
|
*/
|
|
|
|
meta_ctx add_lift(meta_ctx const & ctx, unsigned s, unsigned n);
|
|
|
|
|
2013-09-13 01:25:38 +00:00
|
|
|
/**
|
|
|
|
\brief Add a lift:s:n operation to the context of the given metavariable.
|
|
|
|
|
|
|
|
\pre is_metavar(m)
|
|
|
|
*/
|
|
|
|
expr add_lift(expr const & m, unsigned s, unsigned n);
|
|
|
|
|
|
|
|
/**
|
2013-09-17 02:21:40 +00:00
|
|
|
\brief Add an inst:s:v operation to the context of the given metavariable.
|
2013-09-13 01:25:38 +00:00
|
|
|
|
|
|
|
\pre is_metavar(m)
|
|
|
|
*/
|
2013-09-17 02:21:40 +00:00
|
|
|
expr add_inst(expr const & m, unsigned s, expr const & v);
|
2013-09-13 01:25:38 +00:00
|
|
|
|
2013-09-16 17:58:56 +00:00
|
|
|
/**
|
2013-09-17 02:21:40 +00:00
|
|
|
\brief Extend the context \c ctx with the entry <tt>inst:s v</tt>
|
2013-09-16 17:58:56 +00:00
|
|
|
*/
|
2013-09-17 02:21:40 +00:00
|
|
|
meta_ctx add_inst(meta_ctx const & ctx, unsigned s, expr const & v);
|
2013-09-16 17:58:56 +00:00
|
|
|
|
2013-09-13 01:25:38 +00:00
|
|
|
/**
|
|
|
|
\brief Return true iff the given metavariable has a non-empty
|
|
|
|
context associated with it.
|
|
|
|
|
|
|
|
\pre is_metavar(m)
|
|
|
|
*/
|
2013-09-19 03:46:00 +00:00
|
|
|
bool has_meta_context(expr const & m);
|
2013-09-13 01:25:38 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
\brief Return the same metavariable, but the head of the context is removed.
|
|
|
|
|
|
|
|
\pre is_metavar(m)
|
2013-09-19 03:46:00 +00:00
|
|
|
\pre has_meta_context(m)
|
2013-09-13 01:25:38 +00:00
|
|
|
*/
|
2013-09-19 03:46:00 +00:00
|
|
|
expr pop_meta_context(expr const & m);
|
|
|
|
|
|
|
|
/**
|
|
|
|
\brief Return true iff \c e has a metavariable that is assigned in menv.
|
|
|
|
*/
|
|
|
|
bool has_assigned_metavar(expr const & e, metavar_env const & menv);
|
2013-09-13 01:25:38 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
\brief Return true iff \c e contains the metavariable with index \c midx.
|
|
|
|
The substitutions in \c menv are taken into account.
|
|
|
|
*/
|
|
|
|
bool has_metavar(expr const & e, unsigned midx, metavar_env const & menv = metavar_env());
|
2013-09-19 03:46:00 +00:00
|
|
|
inline bool has_metavar(expr const & e, expr const & m, metavar_env const & menv = metavar_env()) {
|
|
|
|
return has_metavar(e, metavar_idx(m), menv);
|
|
|
|
}
|
2013-09-13 01:25:38 +00:00
|
|
|
}
|