Factor duplicate code. Add more comments
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
0c071d43af
commit
887f696f66
12 changed files with 119 additions and 171 deletions
|
@ -7,28 +7,15 @@ Author: Leonardo de Moura
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
#include "arith.h"
|
#include "arith.h"
|
||||||
#include "abstract.h"
|
#include "abstract.h"
|
||||||
|
#include "value.h"
|
||||||
#include "environment.h"
|
#include "environment.h"
|
||||||
|
|
||||||
namespace lean {
|
namespace lean {
|
||||||
/** \brief Base class for Nat, Int and Real types */
|
|
||||||
class num_type_value : public value {
|
|
||||||
name m_name;
|
|
||||||
public:
|
|
||||||
num_type_value(char const * name):m_name(name) {}
|
|
||||||
virtual ~num_type_value() {}
|
|
||||||
virtual expr get_type() const { return Type(); }
|
|
||||||
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const { return false; }
|
|
||||||
virtual void display(std::ostream & out) const { out << m_name; }
|
|
||||||
virtual format pp() const { return format(m_name); }
|
|
||||||
virtual unsigned hash() const { return m_name.hash(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
// =======================================
|
// =======================================
|
||||||
// Natural numbers
|
// Natural numbers
|
||||||
class nat_type_value : public num_type_value {
|
class nat_type_value : public type_value {
|
||||||
public:
|
public:
|
||||||
nat_type_value():num_type_value("Nat") {}
|
nat_type_value():type_value("Nat") {}
|
||||||
virtual bool operator==(value const & other) const { return dynamic_cast<nat_type_value const*>(&other) != nullptr; }
|
|
||||||
};
|
};
|
||||||
expr const Nat = mk_value(*(new nat_type_value()));
|
expr const Nat = mk_value(*(new nat_type_value()));
|
||||||
expr mk_nat_type() { return Nat; }
|
expr mk_nat_type() { return Nat; }
|
||||||
|
@ -39,7 +26,7 @@ public:
|
||||||
nat_value_value(mpz const & v):m_val(v) { lean_assert(v >= 0); }
|
nat_value_value(mpz const & v):m_val(v) { lean_assert(v >= 0); }
|
||||||
virtual ~nat_value_value() {}
|
virtual ~nat_value_value() {}
|
||||||
virtual expr get_type() const { return Nat; }
|
virtual expr get_type() const { return Nat; }
|
||||||
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const { return false; }
|
virtual name get_name() const { return name{"Nat", "numeral"}; }
|
||||||
virtual bool operator==(value const & other) const {
|
virtual bool operator==(value const & other) const {
|
||||||
nat_value_value const * _other = dynamic_cast<nat_value_value const*>(&other);
|
nat_value_value const * _other = dynamic_cast<nat_value_value const*>(&other);
|
||||||
return _other && _other->m_val == m_val;
|
return _other && _other->m_val == m_val;
|
||||||
|
@ -64,17 +51,9 @@ mpz const & nat_value_numeral(expr const & e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<char const * Name, typename F>
|
template<char const * Name, typename F>
|
||||||
class nat_bin_op : public value {
|
class nat_bin_op : public const_value {
|
||||||
expr m_type;
|
|
||||||
name m_name;
|
|
||||||
public:
|
public:
|
||||||
nat_bin_op() {
|
nat_bin_op():const_value(name("Nat", Name), Nat >> (Nat >> Nat)) {}
|
||||||
m_type = Nat >> (Nat >> Nat);
|
|
||||||
m_name = name("Nat", Name);
|
|
||||||
}
|
|
||||||
virtual ~nat_bin_op() {}
|
|
||||||
virtual expr get_type() const { return m_type; }
|
|
||||||
virtual bool operator==(value const & other) const { return dynamic_cast<nat_bin_op const*>(&other) != nullptr; }
|
|
||||||
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const {
|
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const {
|
||||||
if (num_args == 3 && is_nat_value(args[1]) && is_nat_value(args[2])) {
|
if (num_args == 3 && is_nat_value(args[1]) && is_nat_value(args[2])) {
|
||||||
r = mk_nat_value(F()(nat_value_numeral(args[1]), nat_value_numeral(args[2])));
|
r = mk_nat_value(F()(nat_value_numeral(args[1]), nat_value_numeral(args[2])));
|
||||||
|
@ -83,9 +62,6 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual void display(std::ostream & out) const { out << m_name; }
|
|
||||||
virtual format pp() const { return format(m_name); }
|
|
||||||
virtual unsigned hash() const { return m_name.hash(); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr char nat_add_name[] = "add";
|
constexpr char nat_add_name[] = "add";
|
||||||
|
@ -98,17 +74,9 @@ struct nat_mul_eval { mpz operator()(mpz const & v1, mpz const & v2) { return v1
|
||||||
typedef nat_bin_op<nat_mul_name, nat_mul_eval> nat_mul_value;
|
typedef nat_bin_op<nat_mul_name, nat_mul_eval> nat_mul_value;
|
||||||
MK_BUILTIN(nat_mul_fn, nat_mul_value);
|
MK_BUILTIN(nat_mul_fn, nat_mul_value);
|
||||||
|
|
||||||
class nat_le_value : public value {
|
class nat_le_value : public const_value {
|
||||||
expr m_type;
|
|
||||||
name m_name;
|
|
||||||
public:
|
public:
|
||||||
nat_le_value() {
|
nat_le_value():const_value(name{"Nat", "le"}, Nat >> (Nat >> Bool)) {}
|
||||||
m_type = Nat >> (Nat >> Bool);
|
|
||||||
m_name = name{"Nat", "le"};
|
|
||||||
}
|
|
||||||
virtual ~nat_le_value() {}
|
|
||||||
virtual expr get_type() const { return m_type; }
|
|
||||||
virtual bool operator==(value const & other) const { return dynamic_cast<nat_le_value const*>(&other) != nullptr; }
|
|
||||||
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const {
|
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const {
|
||||||
if (num_args == 3 && is_nat_value(args[1]) && is_nat_value(args[2])) {
|
if (num_args == 3 && is_nat_value(args[1]) && is_nat_value(args[2])) {
|
||||||
r = mk_bool_value(nat_value_numeral(args[1]) <= nat_value_numeral(args[2]));
|
r = mk_bool_value(nat_value_numeral(args[1]) <= nat_value_numeral(args[2]));
|
||||||
|
@ -117,9 +85,6 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual void display(std::ostream & out) const { out << m_name; }
|
|
||||||
virtual format pp() const { return format(m_name); }
|
|
||||||
virtual unsigned hash() const { return m_name.hash(); }
|
|
||||||
};
|
};
|
||||||
MK_BUILTIN(nat_le_fn, nat_le_value);
|
MK_BUILTIN(nat_le_fn, nat_le_value);
|
||||||
|
|
||||||
|
@ -133,10 +98,9 @@ MK_CONSTANT(nat_id_fn, name({"Nat", "id"}));
|
||||||
|
|
||||||
// =======================================
|
// =======================================
|
||||||
// Integers
|
// Integers
|
||||||
class int_type_value : public num_type_value {
|
class int_type_value : public type_value {
|
||||||
public:
|
public:
|
||||||
int_type_value():num_type_value("Int") {}
|
int_type_value():type_value("Int") {}
|
||||||
virtual bool operator==(value const & other) const { return dynamic_cast<int_type_value const*>(&other) != nullptr; }
|
|
||||||
};
|
};
|
||||||
expr const Int = mk_value(*(new int_type_value()));
|
expr const Int = mk_value(*(new int_type_value()));
|
||||||
expr mk_int_type() { return Int; }
|
expr mk_int_type() { return Int; }
|
||||||
|
@ -147,7 +111,7 @@ public:
|
||||||
int_value_value(mpz const & v):m_val(v) {}
|
int_value_value(mpz const & v):m_val(v) {}
|
||||||
virtual ~int_value_value() {}
|
virtual ~int_value_value() {}
|
||||||
virtual expr get_type() const { return Int; }
|
virtual expr get_type() const { return Int; }
|
||||||
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const { return false; }
|
virtual name get_name() const { return name{"Int", "numeral"}; }
|
||||||
virtual bool operator==(value const & other) const {
|
virtual bool operator==(value const & other) const {
|
||||||
int_value_value const * _other = dynamic_cast<int_value_value const*>(&other);
|
int_value_value const * _other = dynamic_cast<int_value_value const*>(&other);
|
||||||
return _other && _other->m_val == m_val;
|
return _other && _other->m_val == m_val;
|
||||||
|
@ -172,17 +136,9 @@ mpz const & int_value_numeral(expr const & e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<char const * Name, typename F>
|
template<char const * Name, typename F>
|
||||||
class int_bin_op : public value {
|
class int_bin_op : public const_value {
|
||||||
expr m_type;
|
|
||||||
name m_name;
|
|
||||||
public:
|
public:
|
||||||
int_bin_op() {
|
int_bin_op():const_value(name("Int", Name), Int >> (Int >> Int)) {}
|
||||||
m_type = Int >> (Int >> Int);
|
|
||||||
m_name = name("Int", Name);
|
|
||||||
}
|
|
||||||
virtual ~int_bin_op() {}
|
|
||||||
virtual expr get_type() const { return m_type; }
|
|
||||||
virtual bool operator==(value const & other) const { return dynamic_cast<int_bin_op const*>(&other) != nullptr; }
|
|
||||||
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const {
|
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const {
|
||||||
if (num_args == 3 && is_int_value(args[1]) && is_int_value(args[2])) {
|
if (num_args == 3 && is_int_value(args[1]) && is_int_value(args[2])) {
|
||||||
r = mk_int_value(F()(int_value_numeral(args[1]), int_value_numeral(args[2])));
|
r = mk_int_value(F()(int_value_numeral(args[1]), int_value_numeral(args[2])));
|
||||||
|
@ -191,9 +147,6 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual void display(std::ostream & out) const { out << m_name; }
|
|
||||||
virtual format pp() const { return format(m_name); }
|
|
||||||
virtual unsigned hash() const { return m_name.hash(); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr char int_add_name[] = "add";
|
constexpr char int_add_name[] = "add";
|
||||||
|
@ -218,17 +171,9 @@ struct int_div_eval {
|
||||||
typedef int_bin_op<int_div_name, int_div_eval> int_div_value;
|
typedef int_bin_op<int_div_name, int_div_eval> int_div_value;
|
||||||
MK_BUILTIN(int_div_fn, int_div_value);
|
MK_BUILTIN(int_div_fn, int_div_value);
|
||||||
|
|
||||||
class int_le_value : public value {
|
class int_le_value : public const_value {
|
||||||
expr m_type;
|
|
||||||
name m_name;
|
|
||||||
public:
|
public:
|
||||||
int_le_value() {
|
int_le_value():const_value(name{"Int", "le"}, Int >> (Int >> Bool)) {}
|
||||||
m_type = Int >> (Int >> Bool);
|
|
||||||
m_name = name{"Int", "le"};
|
|
||||||
}
|
|
||||||
virtual ~int_le_value() {}
|
|
||||||
virtual expr get_type() const { return m_type; }
|
|
||||||
virtual bool operator==(value const & other) const { return dynamic_cast<int_le_value const*>(&other) != nullptr; }
|
|
||||||
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const {
|
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const {
|
||||||
if (num_args == 3 && is_int_value(args[1]) && is_int_value(args[2])) {
|
if (num_args == 3 && is_int_value(args[1]) && is_int_value(args[2])) {
|
||||||
r = mk_bool_value(int_value_numeral(args[1]) <= int_value_numeral(args[2]));
|
r = mk_bool_value(int_value_numeral(args[1]) <= int_value_numeral(args[2]));
|
||||||
|
@ -237,9 +182,6 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual void display(std::ostream & out) const { out << m_name; }
|
|
||||||
virtual format pp() const { return format(m_name); }
|
|
||||||
virtual unsigned hash() const { return m_name.hash(); }
|
|
||||||
};
|
};
|
||||||
MK_BUILTIN(int_le_fn, int_le_value);
|
MK_BUILTIN(int_le_fn, int_le_value);
|
||||||
|
|
||||||
|
@ -255,10 +197,9 @@ MK_CONSTANT(int_gt_fn, name({"Int", "gt"}));
|
||||||
|
|
||||||
// =======================================
|
// =======================================
|
||||||
// Reals
|
// Reals
|
||||||
class real_type_value : public num_type_value {
|
class real_type_value : public type_value {
|
||||||
public:
|
public:
|
||||||
real_type_value():num_type_value("Real") {}
|
real_type_value():type_value("Real") {}
|
||||||
virtual bool operator==(value const & other) const { return dynamic_cast<real_type_value const*>(&other) != nullptr; }
|
|
||||||
};
|
};
|
||||||
expr const Real = mk_value(*(new real_type_value()));
|
expr const Real = mk_value(*(new real_type_value()));
|
||||||
expr mk_real_type() { return Real; }
|
expr mk_real_type() { return Real; }
|
||||||
|
@ -269,7 +210,7 @@ public:
|
||||||
real_value_value(mpq const & v):m_val(v) {}
|
real_value_value(mpq const & v):m_val(v) {}
|
||||||
virtual ~real_value_value() {}
|
virtual ~real_value_value() {}
|
||||||
virtual expr get_type() const { return Real; }
|
virtual expr get_type() const { return Real; }
|
||||||
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const { return false; }
|
virtual name get_name() const { return name{"Real", "numeral"}; }
|
||||||
virtual bool operator==(value const & other) const {
|
virtual bool operator==(value const & other) const {
|
||||||
real_value_value const * _other = dynamic_cast<real_value_value const*>(&other);
|
real_value_value const * _other = dynamic_cast<real_value_value const*>(&other);
|
||||||
return _other && _other->m_val == m_val;
|
return _other && _other->m_val == m_val;
|
||||||
|
@ -294,17 +235,9 @@ mpq const & real_value_numeral(expr const & e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<char const * Name, typename F>
|
template<char const * Name, typename F>
|
||||||
class real_bin_op : public value {
|
class real_bin_op : public const_value {
|
||||||
expr m_type;
|
|
||||||
name m_name;
|
|
||||||
public:
|
public:
|
||||||
real_bin_op() {
|
real_bin_op():const_value(name("Real", Name), Real >> (Real >> Real)) {}
|
||||||
m_type = Real >> (Real >> Real);
|
|
||||||
m_name = name("Real", Name);
|
|
||||||
}
|
|
||||||
virtual ~real_bin_op() {}
|
|
||||||
virtual expr get_type() const { return m_type; }
|
|
||||||
virtual bool operator==(value const & other) const { return dynamic_cast<real_bin_op const*>(&other) != nullptr; }
|
|
||||||
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const {
|
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const {
|
||||||
if (num_args == 3 && is_real_value(args[1]) && is_real_value(args[2])) {
|
if (num_args == 3 && is_real_value(args[1]) && is_real_value(args[2])) {
|
||||||
r = mk_real_value(F()(real_value_numeral(args[1]), real_value_numeral(args[2])));
|
r = mk_real_value(F()(real_value_numeral(args[1]), real_value_numeral(args[2])));
|
||||||
|
@ -313,9 +246,6 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual void display(std::ostream & out) const { out << m_name; }
|
|
||||||
virtual format pp() const { return format(m_name); }
|
|
||||||
virtual unsigned hash() const { return m_name.hash(); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr char real_add_name[] = "add";
|
constexpr char real_add_name[] = "add";
|
||||||
|
@ -340,17 +270,9 @@ struct real_div_eval {
|
||||||
typedef real_bin_op<real_div_name, real_div_eval> real_div_value;
|
typedef real_bin_op<real_div_name, real_div_eval> real_div_value;
|
||||||
MK_BUILTIN(real_div_fn, real_div_value);
|
MK_BUILTIN(real_div_fn, real_div_value);
|
||||||
|
|
||||||
class real_le_value : public value {
|
class real_le_value : public const_value {
|
||||||
expr m_type;
|
|
||||||
name m_name;
|
|
||||||
public:
|
public:
|
||||||
real_le_value() {
|
real_le_value():const_value(name{"Real", "le"}, Real >> (Real >> Bool)) {}
|
||||||
m_type = Real >> (Real >> Bool);
|
|
||||||
m_name = name{"Real", "le"};
|
|
||||||
}
|
|
||||||
virtual ~real_le_value() {}
|
|
||||||
virtual expr get_type() const { return m_type; }
|
|
||||||
virtual bool operator==(value const & other) const { return dynamic_cast<real_le_value const*>(&other) != nullptr; }
|
|
||||||
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const {
|
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const {
|
||||||
if (num_args == 3 && is_real_value(args[1]) && is_real_value(args[2])) {
|
if (num_args == 3 && is_real_value(args[1]) && is_real_value(args[2])) {
|
||||||
r = mk_bool_value(real_value_numeral(args[1]) <= real_value_numeral(args[2]));
|
r = mk_bool_value(real_value_numeral(args[1]) <= real_value_numeral(args[2]));
|
||||||
|
@ -359,9 +281,6 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual void display(std::ostream & out) const { out << m_name; }
|
|
||||||
virtual format pp() const { return format(m_name); }
|
|
||||||
virtual unsigned hash() const { return m_name.hash(); }
|
|
||||||
};
|
};
|
||||||
MK_BUILTIN(real_le_fn, real_le_value);
|
MK_BUILTIN(real_le_fn, real_le_value);
|
||||||
|
|
||||||
|
@ -393,17 +312,9 @@ MK_CONSTANT(csch_fn, name("csch"));
|
||||||
|
|
||||||
// =======================================
|
// =======================================
|
||||||
// Coercions
|
// Coercions
|
||||||
class nat_to_int_value : public value {
|
class nat_to_int_value : public const_value {
|
||||||
expr m_type;
|
|
||||||
name m_name;
|
|
||||||
public:
|
public:
|
||||||
nat_to_int_value() {
|
nat_to_int_value():const_value("nat_to_int", Nat >> Int) {}
|
||||||
m_type = Nat >> Int;
|
|
||||||
m_name = "nat_to_int";
|
|
||||||
}
|
|
||||||
virtual ~nat_to_int_value() {}
|
|
||||||
virtual expr get_type() const { return m_type; }
|
|
||||||
virtual bool operator==(value const & other) const { return dynamic_cast<nat_to_int_value const*>(&other) != nullptr; }
|
|
||||||
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const {
|
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const {
|
||||||
if (num_args == 2 && is_nat_value(args[1])) {
|
if (num_args == 2 && is_nat_value(args[1])) {
|
||||||
r = mk_int_value(nat_value_numeral(args[1]));
|
r = mk_int_value(nat_value_numeral(args[1]));
|
||||||
|
@ -412,23 +323,12 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual void display(std::ostream & out) const { out << m_name; }
|
|
||||||
virtual format pp() const { return format(m_name); }
|
|
||||||
virtual unsigned hash() const { return m_name.hash(); }
|
|
||||||
};
|
};
|
||||||
MK_BUILTIN(nat_to_int_fn, nat_to_int_value);
|
MK_BUILTIN(nat_to_int_fn, nat_to_int_value);
|
||||||
|
|
||||||
class int_to_real_value : public value {
|
class int_to_real_value : public const_value {
|
||||||
expr m_type;
|
|
||||||
name m_name;
|
|
||||||
public:
|
public:
|
||||||
int_to_real_value() {
|
int_to_real_value():const_value("int_to_real", Int >> Real) {}
|
||||||
m_type = Int >> Real;
|
|
||||||
m_name = "int_to_real";
|
|
||||||
}
|
|
||||||
virtual ~int_to_real_value() {}
|
|
||||||
virtual expr get_type() const { return m_type; }
|
|
||||||
virtual bool operator==(value const & other) const { return dynamic_cast<int_to_real_value const*>(&other) != nullptr; }
|
|
||||||
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const {
|
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const {
|
||||||
if (num_args == 2 && is_int_value(args[1])) {
|
if (num_args == 2 && is_int_value(args[1])) {
|
||||||
r = mk_real_value(mpq(int_value_numeral(args[1])));
|
r = mk_real_value(mpq(int_value_numeral(args[1])));
|
||||||
|
@ -437,9 +337,6 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual void display(std::ostream & out) const { out << m_name; }
|
|
||||||
virtual format pp() const { return format(m_name); }
|
|
||||||
virtual unsigned hash() const { return m_name.hash(); }
|
|
||||||
};
|
};
|
||||||
MK_BUILTIN(int_to_real_fn, int_to_real_value);
|
MK_BUILTIN(int_to_real_fn, int_to_real_value);
|
||||||
MK_CONSTANT(nat_to_real_fn, name("nat_to_real"));
|
MK_CONSTANT(nat_to_real_fn, name("nat_to_real"));
|
||||||
|
|
|
@ -63,11 +63,7 @@ class bool_type_value : public value {
|
||||||
public:
|
public:
|
||||||
virtual ~bool_type_value() {}
|
virtual ~bool_type_value() {}
|
||||||
virtual expr get_type() const { return Type(); }
|
virtual expr get_type() const { return Type(); }
|
||||||
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const { return false; }
|
virtual name get_name() const { return g_Bool_name; }
|
||||||
virtual bool operator==(value const & other) const { return dynamic_cast<bool_type_value const*>(&other) != nullptr; }
|
|
||||||
virtual void display(std::ostream & out) const { out << g_Bool_name; }
|
|
||||||
virtual format pp() const { return g_Bool_fmt; }
|
|
||||||
virtual unsigned hash() const { return g_Bool_name.hash(); }
|
|
||||||
};
|
};
|
||||||
expr const Bool = mk_value(*(new bool_type_value()));
|
expr const Bool = mk_value(*(new bool_type_value()));
|
||||||
expr mk_bool_type() { return Bool; }
|
expr mk_bool_type() { return Bool; }
|
||||||
|
@ -79,22 +75,21 @@ static char const * g_true_u_str = "\u22A4";
|
||||||
static char const * g_false_u_str = "\u22A5";
|
static char const * g_false_u_str = "\u22A5";
|
||||||
static format g_true_u_fmt(g_true_u_str);
|
static format g_true_u_fmt(g_true_u_str);
|
||||||
static format g_false_u_fmt(g_false_u_str);
|
static format g_false_u_fmt(g_false_u_str);
|
||||||
static char const * g_true_str = "true";
|
static name g_true_name("true");
|
||||||
static char const * g_false_str = "false";
|
static name g_false_name("false");
|
||||||
static format g_true_fmt(g_true_str);
|
static format g_true_fmt(g_true_name);
|
||||||
static format g_false_fmt(g_false_str);
|
static format g_false_fmt(g_false_name);
|
||||||
class bool_value_value : public value {
|
class bool_value_value : public value {
|
||||||
bool m_val;
|
bool m_val;
|
||||||
public:
|
public:
|
||||||
bool_value_value(bool v):m_val(v) {}
|
bool_value_value(bool v):m_val(v) {}
|
||||||
virtual ~bool_value_value() {}
|
virtual ~bool_value_value() {}
|
||||||
virtual expr get_type() const { return Bool; }
|
virtual expr get_type() const { return Bool; }
|
||||||
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const { return false; }
|
virtual name get_name() const { return m_val ? g_true_name : g_false_name; }
|
||||||
virtual bool operator==(value const & other) const {
|
virtual bool operator==(value const & other) const {
|
||||||
bool_value_value const * _other = dynamic_cast<bool_value_value const*>(&other);
|
bool_value_value const * _other = dynamic_cast<bool_value_value const*>(&other);
|
||||||
return _other && _other->m_val == m_val;
|
return _other && _other->m_val == m_val;
|
||||||
}
|
}
|
||||||
virtual void display(std::ostream & out) const { out << (m_val ? g_true_str : g_false_str); }
|
|
||||||
virtual format pp(bool unicode) const {
|
virtual format pp(bool unicode) const {
|
||||||
if (unicode)
|
if (unicode)
|
||||||
return m_val ? g_true_u_fmt : g_false_u_fmt;
|
return m_val ? g_true_u_fmt : g_false_u_fmt;
|
||||||
|
@ -102,7 +97,6 @@ public:
|
||||||
return m_val ? g_true_fmt : g_false_fmt;
|
return m_val ? g_true_fmt : g_false_fmt;
|
||||||
}
|
}
|
||||||
virtual format pp() const { return pp(true); }
|
virtual format pp() const { return pp(true); }
|
||||||
virtual unsigned hash() const { return m_val ? 3 : 5; }
|
|
||||||
bool get_val() const { return m_val; }
|
bool get_val() const { return m_val; }
|
||||||
};
|
};
|
||||||
expr const True = mk_value(*(new bool_value_value(true)));
|
expr const True = mk_value(*(new bool_value_value(true)));
|
||||||
|
@ -139,6 +133,7 @@ public:
|
||||||
}
|
}
|
||||||
virtual ~ite_fn_value() {}
|
virtual ~ite_fn_value() {}
|
||||||
virtual expr get_type() const { return m_type; }
|
virtual expr get_type() const { return m_type; }
|
||||||
|
virtual name get_name() const { return g_ite_name; }
|
||||||
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const {
|
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const {
|
||||||
if (num_args == 5 && is_bool_value(args[2])) {
|
if (num_args == 5 && is_bool_value(args[2])) {
|
||||||
if (to_bool(args[2]))
|
if (to_bool(args[2]))
|
||||||
|
@ -153,10 +148,6 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual bool operator==(value const & other) const { return dynamic_cast<ite_fn_value const*>(&other) != nullptr; }
|
|
||||||
virtual void display(std::ostream & out) const { out << g_ite_name; }
|
|
||||||
virtual format pp() const { return g_ite_fmt; }
|
|
||||||
virtual unsigned hash() const { return g_ite_name.hash(); }
|
|
||||||
};
|
};
|
||||||
MK_BUILTIN(ite_fn, ite_fn_value);
|
MK_BUILTIN(ite_fn, ite_fn_value);
|
||||||
// =======================================
|
// =======================================
|
||||||
|
|
|
@ -80,33 +80,33 @@ expr_eq::expr_eq(expr const & lhs, expr const & rhs):
|
||||||
m_lhs(lhs),
|
m_lhs(lhs),
|
||||||
m_rhs(rhs) {
|
m_rhs(rhs) {
|
||||||
}
|
}
|
||||||
expr_eq::~expr_eq() {
|
expr_eq::~expr_eq() {}
|
||||||
}
|
|
||||||
expr_abstraction::expr_abstraction(expr_kind k, name const & n, expr const & t, expr const & b):
|
expr_abstraction::expr_abstraction(expr_kind k, name const & n, expr const & t, expr const & b):
|
||||||
expr_cell(k, ::lean::hash(t.hash(), b.hash())),
|
expr_cell(k, ::lean::hash(t.hash(), b.hash())),
|
||||||
m_name(n),
|
m_name(n),
|
||||||
m_domain(t),
|
m_domain(t),
|
||||||
m_body(b) {
|
m_body(b) {
|
||||||
}
|
}
|
||||||
expr_lambda::expr_lambda(name const & n, expr const & t, expr const & e):
|
expr_lambda::expr_lambda(name const & n, expr const & t, expr const & e):expr_abstraction(expr_kind::Lambda, n, t, e) {}
|
||||||
expr_abstraction(expr_kind::Lambda, n, t, e) {}
|
expr_pi::expr_pi(name const & n, expr const & t, expr const & e):expr_abstraction(expr_kind::Pi, n, t, e) {}
|
||||||
expr_pi::expr_pi(name const & n, expr const & t, expr const & e):
|
|
||||||
expr_abstraction(expr_kind::Pi, n, t, e) {}
|
|
||||||
|
|
||||||
expr_type::expr_type(level const & l):
|
expr_type::expr_type(level const & l):
|
||||||
expr_cell(expr_kind::Type, l.hash()),
|
expr_cell(expr_kind::Type, l.hash()),
|
||||||
m_level(l) {
|
m_level(l) {
|
||||||
}
|
}
|
||||||
expr_type::~expr_type() {
|
expr_type::~expr_type() {}
|
||||||
}
|
|
||||||
expr_let::expr_let(name const & n, expr const & v, expr const & b):
|
expr_let::expr_let(name const & n, expr const & v, expr const & b):
|
||||||
expr_cell(expr_kind::Let, ::lean::hash(v.hash(), b.hash())),
|
expr_cell(expr_kind::Let, ::lean::hash(v.hash(), b.hash())),
|
||||||
m_name(n),
|
m_name(n),
|
||||||
m_value(v),
|
m_value(v),
|
||||||
m_body(b) {
|
m_body(b) {
|
||||||
}
|
}
|
||||||
expr_let::~expr_let() {
|
expr_let::~expr_let() {}
|
||||||
}
|
bool value::normalize(unsigned num_args, expr const * args, expr & r) const { return false; }
|
||||||
|
void value::display(std::ostream & out) const { out << get_name(); }
|
||||||
|
bool value::operator==(value const & other) const { return typeid(*this) == typeid(other); }
|
||||||
|
format value::pp() const { return format(get_name()); }
|
||||||
|
format value::pp(bool unicode) const { return pp(); }
|
||||||
|
unsigned value::hash() const { return get_name().hash(); }
|
||||||
expr_value::expr_value(value & v):
|
expr_value::expr_value(value & v):
|
||||||
expr_cell(expr_kind::Value, v.hash()),
|
expr_cell(expr_kind::Value, v.hash()),
|
||||||
m_val(v) {
|
m_val(v) {
|
||||||
|
|
|
@ -204,12 +204,13 @@ public:
|
||||||
value():m_rc(0) {}
|
value():m_rc(0) {}
|
||||||
virtual ~value() {}
|
virtual ~value() {}
|
||||||
virtual expr get_type() const = 0;
|
virtual expr get_type() const = 0;
|
||||||
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const = 0;
|
virtual name get_name() const = 0;
|
||||||
virtual bool operator==(value const & other) const = 0;
|
virtual bool normalize(unsigned num_args, expr const * args, expr & r) const;
|
||||||
virtual void display(std::ostream & out) const = 0;
|
virtual bool operator==(value const & other) const;
|
||||||
virtual format pp() const = 0;
|
virtual void display(std::ostream & out) const;
|
||||||
virtual format pp(bool unicode) const { return pp(); }
|
virtual format pp() const;
|
||||||
virtual unsigned hash() const = 0;
|
virtual format pp(bool unicode) const;
|
||||||
|
virtual unsigned hash() const;
|
||||||
};
|
};
|
||||||
/** \brief Semantic attachments */
|
/** \brief Semantic attachments */
|
||||||
class expr_value : public expr_cell {
|
class expr_value : public expr_cell {
|
||||||
|
@ -223,7 +224,6 @@ public:
|
||||||
};
|
};
|
||||||
// =======================================
|
// =======================================
|
||||||
|
|
||||||
|
|
||||||
// =======================================
|
// =======================================
|
||||||
// Testers
|
// Testers
|
||||||
inline bool is_var(expr_cell * e) { return e->kind() == expr_kind::Var; }
|
inline bool is_var(expr_cell * e) { return e->kind() == expr_kind::Var; }
|
||||||
|
|
|
@ -63,10 +63,13 @@ inline bool is_uvar(level const & l) { return kind(l) == level_kind::UVar; }
|
||||||
inline bool is_lift(level const & l) { return kind(l) == level_kind::Lift; }
|
inline bool is_lift(level const & l) { return kind(l) == level_kind::Lift; }
|
||||||
inline bool is_max (level const & l) { return kind(l) == level_kind::Max; }
|
inline bool is_max (level const & l) { return kind(l) == level_kind::Max; }
|
||||||
|
|
||||||
|
/** \brief Return a */
|
||||||
inline level const * max_begin_levels(level const & l) { return &max_level(l, 0); }
|
inline level const * max_begin_levels(level const & l) { return &max_level(l, 0); }
|
||||||
inline level const * max_end_levels(level const & l) { return max_begin_levels(l) + max_size(l); }
|
inline level const * max_end_levels(level const & l) { return max_begin_levels(l) + max_size(l); }
|
||||||
|
|
||||||
|
/** \brief Pretty print the given level expression, unicode characters are used if \c unicode is \c true. */
|
||||||
format pp(level const & l, bool unicode);
|
format pp(level const & l, bool unicode);
|
||||||
|
/** \brief Pretty print the given level expression using the given configuration options. */
|
||||||
format pp(level const & l, options const & opts = options());
|
format pp(level const & l, options const & opts = options());
|
||||||
}
|
}
|
||||||
void print(lean::level const & l);
|
void print(lean::level const & l);
|
||||||
|
|
33
src/kernel/value.h
Normal file
33
src/kernel/value.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
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 "expr.h"
|
||||||
|
|
||||||
|
namespace lean {
|
||||||
|
// Some value subclasses that capture common implementation patterns.
|
||||||
|
class named_value : public value {
|
||||||
|
name m_name;
|
||||||
|
public:
|
||||||
|
named_value(name const & n):m_name(n) {}
|
||||||
|
virtual ~named_value() {}
|
||||||
|
virtual name get_name() const { return m_name; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class const_value : public named_value {
|
||||||
|
expr m_type;
|
||||||
|
public:
|
||||||
|
const_value(name const & n, expr const & t):named_value(n), m_type(t) {}
|
||||||
|
virtual ~const_value() {}
|
||||||
|
virtual expr get_type() const { return m_type; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class type_value : public named_value {
|
||||||
|
public:
|
||||||
|
type_value(name const & n):named_value(n) {}
|
||||||
|
virtual expr get_type() const { return Type(); }
|
||||||
|
};
|
||||||
|
}
|
|
@ -23,14 +23,12 @@ namespace lean {
|
||||||
value V_i, then we just use (fake T_i).
|
value V_i, then we just use (fake T_i).
|
||||||
*/
|
*/
|
||||||
expr context_to_lambda(context const & c, expr const & e);
|
expr context_to_lambda(context const & c, expr const & e);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Return true if \c e is a fake context created using
|
\brief Return true if \c e is a fake context created using
|
||||||
context_to_lambda.
|
context_to_lambda.
|
||||||
(lambda (n_1 : (fake T_1 V_1)) ... (lambda (n_k : (fake T_k V_k)) e))
|
(lambda (n_1 : (fake T_1 V_1)) ... (lambda (n_k : (fake T_k V_k)) e))
|
||||||
*/
|
*/
|
||||||
bool is_fake_context(expr const & e);
|
bool is_fake_context(expr const & e);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Return the name n_1 of the head of the (fake) context
|
\brief Return the name n_1 of the head of the (fake) context
|
||||||
(lambda (n_1 : (fake T_1 V_1)) ... (lambda (n_k : (fake T_k V_k)) e))
|
(lambda (n_1 : (fake T_1 V_1)) ... (lambda (n_k : (fake T_k V_k)) e))
|
||||||
|
@ -38,7 +36,6 @@ bool is_fake_context(expr const & e);
|
||||||
\pre is_fake_context(e)
|
\pre is_fake_context(e)
|
||||||
*/
|
*/
|
||||||
name const & fake_context_name(expr const & e);
|
name const & fake_context_name(expr const & e);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Return the domain T_1 of the head of the (fake) context
|
\brief Return the domain T_1 of the head of the (fake) context
|
||||||
(lambda (n_1 : (fake T_1 V_1)) ... (lambda (n_k : (fake T_k V_k)) e))
|
(lambda (n_1 : (fake T_1 V_1)) ... (lambda (n_k : (fake T_k V_k)) e))
|
||||||
|
@ -46,7 +43,6 @@ name const & fake_context_name(expr const & e);
|
||||||
\pre is_fake_context(e)
|
\pre is_fake_context(e)
|
||||||
*/
|
*/
|
||||||
expr const & fake_context_domain(expr const & e);
|
expr const & fake_context_domain(expr const & e);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Return the value V_1 of the head of the (fake) context
|
\brief Return the value V_1 of the head of the (fake) context
|
||||||
(lambda (n_1 : (fake T_1 V_1)) ... (lambda (n_k : (fake T_k V_k)) e))
|
(lambda (n_1 : (fake T_1 V_1)) ... (lambda (n_k : (fake T_k V_k)) e))
|
||||||
|
|
|
@ -38,6 +38,9 @@ public:
|
||||||
virtual void set_interrupt(bool flag) {}
|
virtual void set_interrupt(bool flag) {}
|
||||||
};
|
};
|
||||||
class kernel_exception;
|
class kernel_exception;
|
||||||
|
/**
|
||||||
|
\brief Smart-pointer for the actual formatter object (aka \c formatter_cell).
|
||||||
|
*/
|
||||||
class formatter {
|
class formatter {
|
||||||
std::shared_ptr<formatter_cell> m_cell;
|
std::shared_ptr<formatter_cell> m_cell;
|
||||||
public:
|
public:
|
||||||
|
@ -52,6 +55,8 @@ public:
|
||||||
format operator()(kernel_exception const & ex, options const & opts = options());
|
format operator()(kernel_exception const & ex, options const & opts = options());
|
||||||
void set_interrupt(bool flag) { m_cell->set_interrupt(flag); }
|
void set_interrupt(bool flag) { m_cell->set_interrupt(flag); }
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
\brief Create a simple formatter object based on #printer class.
|
||||||
|
*/
|
||||||
formatter mk_simple_formatter();
|
formatter mk_simple_formatter();
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,10 @@ bool is_atomic(expr const & e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Very basic printer for expressions.
|
||||||
|
It is mainly used when debugging code.
|
||||||
|
*/
|
||||||
struct print_expr_fn {
|
struct print_expr_fn {
|
||||||
std::ostream & m_out;
|
std::ostream & m_out;
|
||||||
|
|
||||||
|
|
|
@ -43,13 +43,16 @@ public:
|
||||||
list & operator=(list const & s) { LEAN_COPY_REF(list, s); }
|
list & operator=(list const & s) { LEAN_COPY_REF(list, s); }
|
||||||
list & operator=(list && s) { LEAN_MOVE_REF(list, s); }
|
list & operator=(list && s) { LEAN_MOVE_REF(list, s); }
|
||||||
|
|
||||||
|
/** \brief Return true iff it is not the empty/nil list. */
|
||||||
operator bool() const { return m_ptr != nullptr; }
|
operator bool() const { return m_ptr != nullptr; }
|
||||||
|
|
||||||
friend bool is_nil(list const & l) { return l.m_ptr == nullptr; }
|
friend bool is_nil(list const & l) { return l.m_ptr == nullptr; }
|
||||||
friend T const & head(list const & l) { lean_assert(!is_nil(l)); return l.m_ptr->m_head; }
|
friend T const & head(list const & l) { lean_assert(!is_nil(l)); return l.m_ptr->m_head; }
|
||||||
friend list const & tail(list const & l) { lean_assert(!is_nil(l)); return l.m_ptr->m_tail; }
|
friend list const & tail(list const & l) { lean_assert(!is_nil(l)); return l.m_ptr->m_tail; }
|
||||||
|
|
||||||
|
/** \brief Pointer equality. Return true iff \c l1 and \c l2 point to the same memory location. */
|
||||||
friend bool is_eqp(list const & l1, list const & l2) { return l1.m_ptr == l2.m_ptr; }
|
friend bool is_eqp(list const & l1, list const & l2) { return l1.m_ptr == l2.m_ptr; }
|
||||||
|
/** \brief Structural equality. */
|
||||||
friend bool operator==(list const & l1, list const & l2) {
|
friend bool operator==(list const & l1, list const & l2) {
|
||||||
cell * it1 = l1.m_ptr;
|
cell * it1 = l1.m_ptr;
|
||||||
cell * it2 = l2.m_ptr;
|
cell * it2 = l2.m_ptr;
|
||||||
|
|
|
@ -26,6 +26,11 @@ public:
|
||||||
name(name const & prefix, unsigned k);
|
name(name const & prefix, unsigned k);
|
||||||
name(name const & other);
|
name(name const & other);
|
||||||
name(name && other);
|
name(name && other);
|
||||||
|
/**
|
||||||
|
\brief Create a hierarchical name using the given strings.
|
||||||
|
Example: <code>name{"foo", "bla", "tst"}</code> creates the hierarchical
|
||||||
|
name <tt>foo::bla::tst</tt>.
|
||||||
|
*/
|
||||||
name(std::initializer_list<char const *> const & l);
|
name(std::initializer_list<char const *> const & l);
|
||||||
~name();
|
~name();
|
||||||
static name const & anonymous();
|
static name const & anonymous();
|
||||||
|
@ -37,7 +42,9 @@ public:
|
||||||
friend bool operator!=(name const & a, name const & b) { return !(a == b); }
|
friend bool operator!=(name const & a, name const & b) { return !(a == b); }
|
||||||
friend bool operator==(name const & a, char const * b);
|
friend bool operator==(name const & a, char const * b);
|
||||||
friend bool operator!=(name const & a, char const * b) { return !(a == b); }
|
friend bool operator!=(name const & a, char const * b) { return !(a == b); }
|
||||||
// total order on hierarchical names.
|
/**
|
||||||
|
\brief Total order on hierarchical names.
|
||||||
|
*/
|
||||||
friend int cmp(name const & a, name const & b) { return cmp(a.m_ptr, b.m_ptr); }
|
friend int cmp(name const & a, name const & b) { return cmp(a.m_ptr, b.m_ptr); }
|
||||||
friend bool operator<(name const & a, name const & b) { return cmp(a, b) < 0; }
|
friend bool operator<(name const & a, name const & b) { return cmp(a, b) < 0; }
|
||||||
friend bool operator>(name const & a, name const & b) { return cmp(a, b) > 0; }
|
friend bool operator>(name const & a, name const & b) { return cmp(a, b) > 0; }
|
||||||
|
@ -48,12 +55,18 @@ public:
|
||||||
bool is_string() const { return kind() == name_kind::STRING; }
|
bool is_string() const { return kind() == name_kind::STRING; }
|
||||||
bool is_numeral() const { return kind() == name_kind::NUMERAL; }
|
bool is_numeral() const { return kind() == name_kind::NUMERAL; }
|
||||||
unsigned get_numeral() const;
|
unsigned get_numeral() const;
|
||||||
|
/**
|
||||||
|
\brief If the tail of the given hierarchical name is a string, then it returns this string.
|
||||||
|
\pre is_string()
|
||||||
|
*/
|
||||||
char const * get_string() const;
|
char const * get_string() const;
|
||||||
bool is_atomic() const;
|
bool is_atomic() const;
|
||||||
name get_prefix() const;
|
|
||||||
/**
|
/**
|
||||||
\brief Convert this hierarchical name into a string.
|
\brief Return the prefix of a hierarchical name
|
||||||
|
\pre !is_atomic()
|
||||||
*/
|
*/
|
||||||
|
name get_prefix() const;
|
||||||
|
/** \brief Convert this hierarchical name into a string. */
|
||||||
std::string to_string() const;
|
std::string to_string() const;
|
||||||
/** \brief Size of the this name (in characters). */
|
/** \brief Size of the this name (in characters). */
|
||||||
size_t size() const;
|
size_t size() const;
|
||||||
|
|
|
@ -144,6 +144,9 @@ template<typename T> inline bool operator==(T const & a, sexpr const & b) { retu
|
||||||
inline bool operator!=(sexpr const & a, sexpr const & b) { return !(a == b); }
|
inline bool operator!=(sexpr const & a, sexpr const & b) { return !(a == b); }
|
||||||
template<typename T> inline bool operator!=(sexpr const & a, T const & b) { return !(a == b); }
|
template<typename T> inline bool operator!=(sexpr const & a, T const & b) { return !(a == b); }
|
||||||
template<typename T> inline bool operator!=(T const & a, sexpr const & b) { return !(a == b); }
|
template<typename T> inline bool operator!=(T const & a, sexpr const & b) { return !(a == b); }
|
||||||
|
/**
|
||||||
|
\brief Total order on S-expressions.
|
||||||
|
*/
|
||||||
int cmp(sexpr const & a, sexpr const & b);
|
int cmp(sexpr const & a, sexpr const & b);
|
||||||
inline bool operator<(sexpr const & a, sexpr const & b) { return cmp(a, b) < 0; }
|
inline bool operator<(sexpr const & a, sexpr const & b) { return cmp(a, b) < 0; }
|
||||||
inline bool operator>(sexpr const & a, sexpr const & b) { return cmp(a, b) > 0; }
|
inline bool operator>(sexpr const & a, sexpr const & b) { return cmp(a, b) > 0; }
|
||||||
|
|
Loading…
Reference in a new issue