2014-02-23 21:19:39 +00:00
|
|
|
/*
|
|
|
|
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
|
2014-02-23 22:41:44 +00:00
|
|
|
#include <algorithm>
|
2014-02-23 21:19:39 +00:00
|
|
|
#include "kernel/expr.h"
|
|
|
|
#include "kernel/justification.h"
|
|
|
|
namespace lean {
|
|
|
|
/**
|
|
|
|
\brief The lean kernel type checker produces three kinds of constraints:
|
|
|
|
|
|
|
|
- Equality constraint: t ≈ s
|
|
|
|
The terms t and s must be definitionally equal.
|
|
|
|
- Convertability constraint: t ↠ s
|
|
|
|
The term t must be convertible to s
|
|
|
|
- Universe level constaint: l ≤ m
|
|
|
|
The universe level l must be less than or equal to m.
|
|
|
|
|
|
|
|
\remark The first two kinds are only generated if the input term
|
|
|
|
contains metavariables.
|
|
|
|
|
|
|
|
Each constraint is associated with a justification object.
|
|
|
|
|
|
|
|
Finally, we also include a choice constraint. The choice is an auxiliary
|
|
|
|
constraint used to implement overloading and coercions in Lean.
|
|
|
|
This constraint is not generated by the kernel.
|
|
|
|
A choice constraint has the form:
|
|
|
|
t ∊ {s_1, ..., s_k}
|
|
|
|
It means, t must be definitionally equal to one of the terms in the (finite)
|
|
|
|
set {s_1, ..., s_k}.
|
|
|
|
*/
|
|
|
|
enum constraint_kind { Eq, Convertible, Level, Choice };
|
|
|
|
struct constraint_cell;
|
|
|
|
class constraint {
|
|
|
|
constraint_cell * m_ptr;
|
|
|
|
constraint(constraint_cell * ptr);
|
|
|
|
public:
|
|
|
|
constraint(constraint const & c);
|
|
|
|
constraint(constraint && s);
|
|
|
|
~constraint();
|
|
|
|
|
|
|
|
constraint_kind kind() const;
|
|
|
|
unsigned hash() const;
|
|
|
|
justification const & get_justification() const;
|
|
|
|
|
|
|
|
constraint & operator=(constraint const & c);
|
|
|
|
constraint & operator=(constraint && c);
|
|
|
|
|
|
|
|
friend bool is_eqp(constraint const & c1, constraint const & c2) { return c1.m_ptr == c2.m_ptr; }
|
|
|
|
friend void swap(constraint & l1, constraint & l2) { std::swap(l1, l2); }
|
|
|
|
|
|
|
|
friend constraint mk_eq_cnstr(expr const & lhs, expr const & rhs, justification const & j);
|
|
|
|
friend constraint mk_conv_cnstr(expr const & lhs, expr const & rhs, justification const & j);
|
|
|
|
friend constraint mk_level_cnstr(level const & lhs, level const & rhs, justification const & j);
|
|
|
|
friend constraint mk_choice_cnstr(expr const & t, list<expr> const & s, justification const & j);
|
|
|
|
|
|
|
|
constraint_cell * raw() const { return m_ptr; }
|
|
|
|
};
|
|
|
|
|
|
|
|
bool operator==(constraint const & c1, constraint const & c2);
|
|
|
|
inline bool operator!=(constraint const & c1, constraint const & c2) { return !(c1 == c2); }
|
|
|
|
|
2014-02-25 00:30:56 +00:00
|
|
|
constraint mk_eq_cnstr(expr const & lhs, expr const & rhs, justification const & j);
|
|
|
|
constraint mk_conv_cnstr(expr const & lhs, expr const & rhs, justification const & j);
|
|
|
|
constraint mk_level_cnstr(level const & lhs, level const & rhs, justification const & j);
|
|
|
|
constraint mk_choice_cnstr(expr const & t, list<expr> const & s, justification const & j);
|
|
|
|
|
2014-02-23 21:19:39 +00:00
|
|
|
bool is_eq_cnstr(constraint const & c) { return c.kind() == constraint_kind::Eq; }
|
|
|
|
bool is_conv_cnstr(constraint const & c) { return c.kind() == constraint_kind::Convertible; }
|
|
|
|
bool is_level_cnstr(constraint const & c) { return c.kind() == constraint_kind::Level; }
|
|
|
|
bool is_choice_cnstr(constraint const & c) { return c.kind() == constraint_kind::Choice; }
|
|
|
|
bool is_eqc_cnstr(constraint const & c) { return is_eq_cnstr(c) || is_conv_cnstr(c); }
|
|
|
|
|
|
|
|
/** \brief Return the lhs of an equality/convertability constraint. */
|
|
|
|
expr const & cnstr_lhs_expr(constraint const & c);
|
|
|
|
/** \brief Return the rhs of an equality/convertability constraint. */
|
|
|
|
expr const & cnstr_rhs_expr(constraint const & c);
|
|
|
|
/** \brief Return the lhs of an level constraint. */
|
|
|
|
level const & cnstr_lhs_level(constraint const & c);
|
|
|
|
/** \brief Return the rhs of an level constraint. */
|
|
|
|
level const & cnstr_rhs_level(constraint const & c);
|
|
|
|
/** \brief Return the main term a choice constraint. */
|
|
|
|
expr const & cnstr_choice_expr(constraint const & c);
|
|
|
|
/** \brief Return the choice set of a choice constraint. */
|
|
|
|
list<expr> const & cnstr_choice_set(constraint const & c);
|
|
|
|
|
|
|
|
/** \brief Update equality/convertability constraint c with new_lhs, new_rhs and justification. */
|
|
|
|
constraint updt_eqc_cnstr(constraint const & c, expr const & new_lhs, expr const & new_rhs, justification const & new_jst);
|
|
|
|
/** \brief Update equality/convertability constraint c with new_lhs and new_rhs, but keeping the same justification. */
|
|
|
|
constraint updt_eqc_cnstr(constraint const & c, expr const & new_lhs, expr const & new_rhs);
|
|
|
|
/** \brief Update level constraint c with new_lhs, new_rhs and justification. */
|
|
|
|
constraint updt_level_cnstr(constraint const & c, level const & new_lhs, level const & new_rhs, justification const & new_jst);
|
|
|
|
/** \brief Update level constraint c with new_lhs and new_rhs, but keeping the same justification. */
|
|
|
|
constraint updt_level_cnstr(constraint const & c, level const & new_lhs, level const & new_rhs);
|
|
|
|
|
|
|
|
/** \brief Printer for debugging purposes */
|
|
|
|
std::ostream & operator<<(std::ostream & out, constraint const & c);
|
|
|
|
|
|
|
|
typedef list<constraint> constraints;
|
2014-02-25 00:30:56 +00:00
|
|
|
inline constraints add(constraints const & cs, constraint const & c) { return cons(c, cs); }
|
2014-02-23 21:19:39 +00:00
|
|
|
}
|