#include <iostream>
#include "Kernel/Theory.hpp"
#include "Lib/List.hpp"
#include "Lib/BitUtils.hpp"
#include "Kernel/Theory.hpp"
#include "Lib/Int.hpp"
#include "Test/UnitTesting.hpp"
using namespace std;
using namespace Lib;
using namespace Kernel;
static unsigned safeAbs(const int num)
{
if(num == std::numeric_limits<int>::min()) { return (unsigned)num; }
return std::abs(num);
}
TEST_FUN(list_1)
{
IntList* lst = 0;
IntList::push(0, lst);
IntList::push(1, lst);
IntList::DelIterator dit(lst);
ALWAYS(dit.hasNext());
ALWAYS(dit.next()==1);
dit.del();
ASS_EQ(lst->head(), 0);
ASS_ALLOC_TYPE(lst, "List");
}
inline auto ict(int i) -> IntegerConstantType { return IntegerConstantType(i); }
inline auto rct(int i) -> RationalConstantType { return RationalConstantType(ict(i)); }
inline auto rct(int i, int j) -> RationalConstantType { return RationalConstantType(ict(i), ict(j)); }
TEST_FUN(test01) {
for (int i = -512; i <= 512; i++) {
auto exp = ict(BitUtils::log2(safeAbs(i)));
auto is = ict(i).abs().log2();
if (is != exp ) {
std::cout << "[ fail ] ict(" << i << ").abs().log2()" << std::endl;
std::cout << "[ is ] " << is << std::endl;
std::cout << "[ exp ] " << exp << std::endl;
ASSERTION_VIOLATION
}
}
}
TEST_FUN(divides) {
ASS( ict( 1).divides(ict(15)))
ASS( ict( 3).divides(ict(15)))
ASS( ict( 5).divides(ict(15)))
ASS( ict( -1).divides(ict(15)))
ASS( ict( -3).divides(ict(15)))
ASS( ict( -5).divides(ict(15)))
ASS( ict( 3).divides(ict(-15)))
ASS( ict( 5).divides(ict(-15)))
ASS( ict( 1).divides(ict(-15)))
ASS( ict( -1).divides(ict(-15)))
ASS( ict( -3).divides(ict(-15)))
ASS( ict( -5).divides(ict(-15)))
ASS(!ict( 7).divides(ict(15)))
ASS(!ict( -7).divides(ict(15)))
ASS(!ict( 15).divides(ict(3)))
ASS(!ict(-15).divides(ict(3)))
}
TEST_FUN(floor) {
ASS_EQ( rct(3,5).floor(), 0 )
ASS_EQ( rct(7,5).floor(), 1 )
ASS_EQ( rct(10,5).floor(), 2 )
ASS_EQ( rct(12,5).floor(), 2 )
ASS_EQ( rct(-12,5).floor(), -3 )
ASS_EQ( rct(-10,5).floor(), -2 )
ASS_EQ( rct( -7,5).floor(), -2 )
ASS_EQ( rct( -3,5).floor(), -1 )
}
TEST_FUN(ceiling) {
ASS_EQ( rct(3,5).ceiling(), 1 )
ASS_EQ( rct(7,5).ceiling(), 2 )
ASS_EQ( rct(10,5).ceiling(), 2 )
ASS_EQ( rct(12,5).ceiling(), 3 )
ASS_EQ( rct(-12,5).ceiling(), -2 )
ASS_EQ( rct(-10,5).ceiling(), -2 )
ASS_EQ( rct( -7,5).ceiling(), -1 )
ASS_EQ( rct( -3,5).ceiling(), 0 )
}
TEST_FUN(precedence) {
ASS_EQ(Comparison::LESS, IntegerConstantType::comparePrecedence(ict( 1), ict(-1)))
ASS_EQ(Comparison::LESS, IntegerConstantType::comparePrecedence(ict( 1), ict( 3)))
ASS_EQ(Comparison::LESS, IntegerConstantType::comparePrecedence(ict(-1), ict( 3)))
ASS_EQ(Comparison::LESS, IntegerConstantType::comparePrecedence(ict( 1), ict(-3)))
ASS_EQ(Comparison::LESS, IntegerConstantType::comparePrecedence(ict(-1), ict(-3)))
}
TEST_FUN(inverse_modulo_m) {
auto max = IntegerConstantType(512);
for (auto i : range(0, max)) {
for (auto m : range(1, max)) {
if (i.gcd(m) == 1) {
auto oneModM = IntegerConstantType(1).remainderE(m);
auto inv = i.inverseModulo(m);
ASS_EQ((i * inv).remainderE(m), oneModM)
}
}
}
}
TEST_FUN(to_string)
{
for (std::string str : {
"1111111111111111111111111111111111111111111",
"-1111111111111111111111111111111111111111111",
"1111111189123097123890102111111111111111111",
}) {
ASS_EQ(Output::toString(IntegerConstantType::parse(str).unwrap()), str);
}
}
TEST_FUN(parse_real)
{
ASS_EQ(RealConstantType::parse("0.123E20"),
RealConstantType::parse("12300000000000000000"));
ASS_EQ(RealConstantType::parse("0.123e20"),
RealConstantType::parse("12300000000000000000"));
ASS_EQ(RealConstantType::parse("0.123E-8"),
RealConstantType::parse("0.00000000123"));
ASS_EQ(RealConstantType::parse("0.123e-8"),
RealConstantType::parse("0.00000000123"));
}