2014-07-02 15:08:35 +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
|
|
|
|
*/
|
|
|
|
#include "kernel/type_checker.h"
|
|
|
|
#include "library/num.h"
|
2015-01-24 00:50:32 +00:00
|
|
|
#include "library/constants.h"
|
2014-07-02 15:08:35 +00:00
|
|
|
|
|
|
|
namespace lean {
|
2014-09-23 17:45:14 +00:00
|
|
|
static expr * g_num = nullptr;
|
|
|
|
static expr * g_pos_num = nullptr;
|
|
|
|
static expr * g_zero = nullptr;
|
|
|
|
static expr * g_pos = nullptr;
|
|
|
|
static expr * g_one = nullptr;
|
|
|
|
static expr * g_bit0 = nullptr;
|
|
|
|
static expr * g_bit1 = nullptr;
|
|
|
|
|
|
|
|
void initialize_num() {
|
2015-01-24 00:50:32 +00:00
|
|
|
g_num = new expr(Const(get_num_name()));
|
|
|
|
g_pos_num = new expr(Const(get_pos_num_name()));
|
|
|
|
g_zero = new expr(Const(get_num_zero_name()));
|
|
|
|
g_pos = new expr(Const(get_num_pos_name()));
|
|
|
|
g_one = new expr(Const(get_pos_num_one_name()));
|
|
|
|
g_bit0 = new expr(Const(get_pos_num_bit0_name()));
|
|
|
|
g_bit1 = new expr(Const(get_pos_num_bit1_name()));
|
2014-09-23 17:45:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void finalize_num() {
|
|
|
|
delete g_num;
|
|
|
|
delete g_pos_num;
|
|
|
|
delete g_zero;
|
|
|
|
delete g_pos;
|
|
|
|
delete g_one;
|
|
|
|
delete g_bit0;
|
|
|
|
delete g_bit1;
|
|
|
|
}
|
2014-07-02 15:08:35 +00:00
|
|
|
|
|
|
|
bool has_num_decls(environment const & env) {
|
|
|
|
try {
|
|
|
|
type_checker tc(env);
|
|
|
|
return
|
2014-09-23 17:45:14 +00:00
|
|
|
tc.infer(*g_zero).first == *g_num &&
|
|
|
|
tc.infer(*g_pos).first == mk_arrow(*g_pos_num, *g_num) &&
|
|
|
|
tc.infer(*g_one).first == *g_pos_num &&
|
|
|
|
tc.infer(*g_bit0).first == mk_arrow(*g_pos_num, *g_pos_num) &&
|
|
|
|
tc.infer(*g_bit1).first == mk_arrow(*g_pos_num, *g_pos_num);
|
2015-01-15 23:05:47 +00:00
|
|
|
} catch (exception&) {
|
2014-07-02 15:08:35 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
expr from_pos_num(mpz const & n) {
|
|
|
|
lean_assert(n > 0);
|
|
|
|
if (n == 1)
|
2014-09-23 17:45:14 +00:00
|
|
|
return *g_one;
|
2014-07-02 15:08:35 +00:00
|
|
|
if (n % mpz(2) == 1)
|
2014-09-23 17:45:14 +00:00
|
|
|
return mk_app(*g_bit1, from_pos_num(n / 2));
|
2014-07-02 15:08:35 +00:00
|
|
|
else
|
2014-09-23 17:45:14 +00:00
|
|
|
return mk_app(*g_bit0, from_pos_num(n / 2));
|
2014-07-02 15:08:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
expr from_num(mpz const & n) {
|
|
|
|
expr r;
|
|
|
|
lean_assert(n >= 0);
|
|
|
|
if (n == 0)
|
2014-09-23 17:45:14 +00:00
|
|
|
r = *g_zero;
|
2014-07-02 15:08:35 +00:00
|
|
|
else
|
2014-09-23 17:45:14 +00:00
|
|
|
r = mk_app(*g_pos, from_pos_num(n));
|
2014-07-02 15:08:35 +00:00
|
|
|
lean_assert(*to_num(r) == n);
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2014-08-14 16:08:39 +00:00
|
|
|
optional<mpz> to_pos_num(expr const & e) {
|
2014-09-23 17:45:14 +00:00
|
|
|
if (e == *g_one) {
|
2014-08-14 16:08:39 +00:00
|
|
|
return some(mpz(1));
|
2014-08-26 15:18:07 +00:00
|
|
|
} else if (is_app(e)) {
|
2014-09-23 17:45:14 +00:00
|
|
|
if (app_fn(e) == *g_bit0) {
|
2014-08-26 15:18:07 +00:00
|
|
|
if (auto r = to_pos_num(app_arg(e)))
|
|
|
|
return some(2*(*r));
|
2014-09-23 17:45:14 +00:00
|
|
|
} else if (app_fn(e) == *g_bit1) {
|
2014-08-26 15:18:07 +00:00
|
|
|
if (auto r = to_pos_num(app_arg(e)))
|
|
|
|
return some(2*(*r) + 1);
|
|
|
|
}
|
2014-08-14 16:08:39 +00:00
|
|
|
}
|
|
|
|
return optional<mpz>();
|
2014-07-02 15:08:35 +00:00
|
|
|
}
|
|
|
|
|
2014-08-14 16:08:39 +00:00
|
|
|
optional<mpz> to_num(expr const & e) {
|
2014-09-23 17:45:14 +00:00
|
|
|
if (e == *g_zero)
|
2014-08-14 16:08:39 +00:00
|
|
|
return some(mpz(0));
|
2014-09-23 17:45:14 +00:00
|
|
|
else if (is_app(e) && app_fn(e) == *g_pos)
|
2014-08-14 16:08:39 +00:00
|
|
|
return to_pos_num(app_arg(e));
|
2014-07-02 15:08:35 +00:00
|
|
|
else
|
|
|
|
return optional<mpz>();
|
|
|
|
}
|
|
|
|
}
|