/* 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 #include #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 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); } 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 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 constraints; }