You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
555 lines
19 KiB
555 lines
19 KiB
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <pthread.h>
|
|
#include <unistd.h>
|
|
#include <time.h>
|
|
#include <sys/types.h>
|
|
#include <sys/time.h>
|
|
#include <inttypes.h>
|
|
|
|
#include "sylvan.h"
|
|
#include "test_assert.h"
|
|
#include "sylvan_int.h"
|
|
|
|
__thread uint64_t seed = 1;
|
|
|
|
uint64_t
|
|
xorshift_rand(void)
|
|
{
|
|
uint64_t x = seed;
|
|
if (seed == 0) seed = rand();
|
|
x ^= x >> 12;
|
|
x ^= x << 25;
|
|
x ^= x >> 27;
|
|
seed = x;
|
|
return x * 2685821657736338717LL;
|
|
}
|
|
|
|
double
|
|
uniform_deviate(uint64_t seed)
|
|
{
|
|
return seed * (1.0 / (0xffffffffffffffffL + 1.0));
|
|
}
|
|
|
|
int
|
|
rng(int low, int high)
|
|
{
|
|
return low + uniform_deviate(xorshift_rand()) * (high-low);
|
|
}
|
|
|
|
static int
|
|
test_cache()
|
|
{
|
|
test_assert(cache_getused() == 0);
|
|
|
|
/**
|
|
* Test cache for large number of random entries
|
|
*/
|
|
|
|
size_t number_add = 4000000;
|
|
uint64_t *arr = (uint64_t*)malloc(sizeof(uint64_t)*4*number_add);
|
|
for (size_t i=0; i<number_add*4; i++) arr[i] = xorshift_rand();
|
|
for (size_t i=0; i<number_add; i++) {
|
|
test_assert(cache_put(arr[4*i], arr[4*i+1], arr[4*i+2], arr[4*i+3]));
|
|
uint64_t val;
|
|
int res = cache_get(arr[4*i], arr[4*i+1], arr[4*i+2], &val);
|
|
test_assert(res == 1);
|
|
test_assert(val == arr[4*i+3]);
|
|
}
|
|
size_t count = 0;
|
|
for (size_t i=0; i<number_add; i++) {
|
|
uint64_t val;
|
|
int res = cache_get(arr[4*i], arr[4*i+1], arr[4*i+2], &val);
|
|
test_assert(res == 0 || val == arr[4*i+3]);
|
|
if (res) count++;
|
|
}
|
|
test_assert(count == cache_getused());
|
|
|
|
/**
|
|
* Now also test for double entries
|
|
*/
|
|
|
|
for (size_t i=0; i<number_add/2; i++) {
|
|
test_assert(cache_put6(arr[8*i], arr[8*i+1], arr[8*i+2], arr[8*i+3], arr[8*i+4], arr[8*i+5], arr[8*i+6], arr[8*i+7]));
|
|
uint64_t val1, val2;
|
|
int res = cache_get6(arr[8*i], arr[8*i+1], arr[8*i+2], arr[8*i+3], arr[8*i+4], arr[8*i+5], &val1, &val2);
|
|
test_assert(res == 1);
|
|
test_assert(val1 == arr[8*i+6]);
|
|
test_assert(val2 == arr[8*i+7]);
|
|
}
|
|
for (size_t i=0; i<number_add/2; i++) {
|
|
uint64_t val1, val2;
|
|
int res = cache_get6(arr[8*i], arr[8*i+1], arr[8*i+2], arr[8*i+3], arr[8*i+4], arr[8*i+5], &val1, &val2);
|
|
test_assert(res == 0 || (val1 == arr[8*i+6] && val2 == arr[8*i+7]));
|
|
}
|
|
|
|
/**
|
|
* And test that single entries are not corrupted
|
|
*/
|
|
for (size_t i=0; i<number_add; i++) {
|
|
uint64_t val;
|
|
int res = cache_get(arr[4*i], arr[4*i+1], arr[4*i+2], &val);
|
|
test_assert(res == 0 || val == arr[4*i+3]);
|
|
}
|
|
|
|
/**
|
|
* TODO: multithreaded test
|
|
*/
|
|
|
|
free(arr);
|
|
return 0;
|
|
}
|
|
|
|
static inline BDD
|
|
make_random(int i, int j)
|
|
{
|
|
if (i == j) return rng(0, 2) ? sylvan_true : sylvan_false;
|
|
|
|
BDD yes = make_random(i+1, j);
|
|
BDD no = make_random(i+1, j);
|
|
BDD result = sylvan_invalid;
|
|
|
|
switch(rng(0, 4)) {
|
|
case 0:
|
|
result = no;
|
|
sylvan_deref(yes);
|
|
break;
|
|
case 1:
|
|
result = yes;
|
|
sylvan_deref(no);
|
|
break;
|
|
case 2:
|
|
result = sylvan_ref(sylvan_makenode(i, yes, no));
|
|
sylvan_deref(no);
|
|
sylvan_deref(yes);
|
|
break;
|
|
case 3:
|
|
default:
|
|
result = sylvan_ref(sylvan_makenode(i, no, yes));
|
|
sylvan_deref(no);
|
|
sylvan_deref(yes);
|
|
break;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
static MDD
|
|
make_random_ldd_set(int depth, int maxvalue, int elements)
|
|
{
|
|
uint32_t values[depth];
|
|
MDD result = mtbdd_false; // empty set
|
|
for (int i=0; i<elements; i++) {
|
|
lddmc_refs_push(result);
|
|
for (int j=0; j<depth; j++) {
|
|
values[j] = rng(0, maxvalue);
|
|
}
|
|
result = lddmc_union_cube(result, values, depth);
|
|
lddmc_refs_pop(1);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
int testEqual(BDD a, BDD b)
|
|
{
|
|
if (a == b) return 1;
|
|
|
|
if (a == sylvan_invalid) {
|
|
fprintf(stderr, "a is invalid!\n");
|
|
return 0;
|
|
}
|
|
|
|
if (b == sylvan_invalid) {
|
|
fprintf(stderr, "b is invalid!\n");
|
|
return 0;
|
|
}
|
|
|
|
fprintf(stderr, "a and b are not equal!\n");
|
|
|
|
sylvan_fprint(stderr, a);fprintf(stderr, "\n");
|
|
sylvan_fprint(stderr, b);fprintf(stderr, "\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
test_bdd()
|
|
{
|
|
test_assert(sylvan_makenode(sylvan_ithvar(1), sylvan_true, sylvan_true) == sylvan_not(sylvan_makenode(sylvan_ithvar(1), sylvan_false, sylvan_false)));
|
|
test_assert(sylvan_makenode(sylvan_ithvar(1), sylvan_false, sylvan_true) == sylvan_not(sylvan_makenode(sylvan_ithvar(1), sylvan_true, sylvan_false)));
|
|
test_assert(sylvan_makenode(sylvan_ithvar(1), sylvan_true, sylvan_false) == sylvan_not(sylvan_makenode(sylvan_ithvar(1), sylvan_false, sylvan_true)));
|
|
test_assert(sylvan_makenode(sylvan_ithvar(1), sylvan_false, sylvan_false) == sylvan_not(sylvan_makenode(sylvan_ithvar(1), sylvan_true, sylvan_true)));
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
test_cube()
|
|
{
|
|
LACE_ME;
|
|
const BDDSET vars = sylvan_set_fromarray(((BDDVAR[]){1,2,3,4,6,8}), 6);
|
|
|
|
uint8_t cube[6], check[6];
|
|
int i, j;
|
|
for (i=0;i<6;i++) cube[i] = rng(0,3);
|
|
BDD bdd = sylvan_cube(vars, cube);
|
|
|
|
sylvan_sat_one(bdd, vars, check);
|
|
for (i=0; i<6;i++) test_assert(cube[i] == check[i] || (cube[i] == 2 && check[i] == 0));
|
|
|
|
BDD picked_single = sylvan_pick_single_cube(bdd, vars);
|
|
test_assert(testEqual(sylvan_and(picked_single, bdd), picked_single));
|
|
assert(sylvan_satcount(picked_single, vars)==1);
|
|
|
|
BDD picked = sylvan_pick_cube(bdd);
|
|
test_assert(testEqual(sylvan_and(picked, bdd), picked));
|
|
|
|
BDD t1 = sylvan_cube(vars, ((uint8_t[]){1,1,2,2,0,0}));
|
|
BDD t2 = sylvan_cube(vars, ((uint8_t[]){1,1,1,0,0,2}));
|
|
test_assert(testEqual(sylvan_union_cube(t1, vars, ((uint8_t[]){1,1,1,0,0,2})), sylvan_or(t1, t2)));
|
|
t2 = sylvan_cube(vars, ((uint8_t[]){2,2,2,1,1,0}));
|
|
test_assert(testEqual(sylvan_union_cube(t1, vars, ((uint8_t[]){2,2,2,1,1,0})), sylvan_or(t1, t2)));
|
|
t2 = sylvan_cube(vars, ((uint8_t[]){1,1,1,0,0,0}));
|
|
test_assert(testEqual(sylvan_union_cube(t1, vars, ((uint8_t[]){1,1,1,0,0,0})), sylvan_or(t1, t2)));
|
|
|
|
bdd = make_random(1, 16);
|
|
for (j=0;j<10;j++) {
|
|
for (i=0;i<6;i++) cube[i] = rng(0,3);
|
|
BDD c = sylvan_cube(vars, cube);
|
|
test_assert(sylvan_union_cube(bdd, vars, cube) == sylvan_or(bdd, c));
|
|
}
|
|
|
|
for (i=0;i<10;i++) {
|
|
picked = sylvan_pick_cube(bdd);
|
|
test_assert(testEqual(sylvan_and(picked, bdd), picked));
|
|
}
|
|
|
|
// simple test for mtbdd_enum_all
|
|
uint8_t arr[6];
|
|
MTBDD leaf = mtbdd_enum_all_first(mtbdd_true, vars, arr, NULL);
|
|
test_assert(leaf == mtbdd_true);
|
|
test_assert(mtbdd_enum_all_first(mtbdd_true, vars, arr, NULL) == mtbdd_true);
|
|
test_assert(arr[0] == 0 && arr[1] == 0 && arr[2] == 0 && arr[3] == 0 && arr[4] == 0 && arr[5] == 0);
|
|
test_assert(mtbdd_enum_all_next(mtbdd_true, vars, arr, NULL) == mtbdd_true);
|
|
test_assert(arr[0] == 0 && arr[1] == 0 && arr[2] == 0 && arr[3] == 0 && arr[4] == 0 && arr[5] == 1);
|
|
test_assert(mtbdd_enum_all_next(mtbdd_true, vars, arr, NULL) == mtbdd_true);
|
|
test_assert(arr[0] == 0 && arr[1] == 0 && arr[2] == 0 && arr[3] == 0 && arr[4] == 1 && arr[5] == 0);
|
|
test_assert(mtbdd_enum_all_next(mtbdd_true, vars, arr, NULL) == mtbdd_true);
|
|
test_assert(arr[0] == 0 && arr[1] == 0 && arr[2] == 0 && arr[3] == 0 && arr[4] == 1 && arr[5] == 1);
|
|
test_assert(mtbdd_enum_all_next(mtbdd_true, vars, arr, NULL) == mtbdd_true);
|
|
test_assert(arr[0] == 0 && arr[1] == 0 && arr[2] == 0 && arr[3] == 1 && arr[4] == 0 && arr[5] == 0);
|
|
test_assert(mtbdd_enum_all_next(mtbdd_true, vars, arr, NULL) == mtbdd_true);
|
|
test_assert(arr[0] == 0 && arr[1] == 0 && arr[2] == 0 && arr[3] == 1 && arr[4] == 0 && arr[5] == 1);
|
|
test_assert(mtbdd_enum_all_next(mtbdd_true, vars, arr, NULL) == mtbdd_true);
|
|
test_assert(arr[0] == 0 && arr[1] == 0 && arr[2] == 0 && arr[3] == 1 && arr[4] == 1 && arr[5] == 0);
|
|
|
|
mtbdd_enum_all_first(mtbdd_true, vars, arr, NULL);
|
|
size_t count = 1;
|
|
while (mtbdd_enum_all_next(mtbdd_true, vars, arr, NULL) != mtbdd_false) {
|
|
test_assert(count < 64);
|
|
count++;
|
|
}
|
|
test_assert(count == 64);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
test_operators()
|
|
{
|
|
// We need to test: xor, and, or, nand, nor, imp, biimp, invimp, diff, less
|
|
LACE_ME;
|
|
|
|
//int i;
|
|
BDD a = sylvan_ithvar(1);
|
|
BDD b = sylvan_ithvar(2);
|
|
BDD one = make_random(1, 12);
|
|
BDD two = make_random(6, 24);
|
|
|
|
// Test or
|
|
test_assert(testEqual(sylvan_or(a, b), sylvan_makenode(1, b, sylvan_true)));
|
|
test_assert(testEqual(sylvan_or(a, b), sylvan_or(b, a)));
|
|
test_assert(testEqual(sylvan_or(one, two), sylvan_or(two, one)));
|
|
|
|
// Test and
|
|
test_assert(testEqual(sylvan_and(a, b), sylvan_makenode(1, sylvan_false, b)));
|
|
test_assert(testEqual(sylvan_and(a, b), sylvan_and(b, a)));
|
|
test_assert(testEqual(sylvan_and(one, two), sylvan_and(two, one)));
|
|
|
|
// Test xor
|
|
test_assert(testEqual(sylvan_xor(a, b), sylvan_makenode(1, b, sylvan_not(b))));
|
|
test_assert(testEqual(sylvan_xor(a, b), sylvan_xor(a, b)));
|
|
test_assert(testEqual(sylvan_xor(a, b), sylvan_xor(b, a)));
|
|
test_assert(testEqual(sylvan_xor(one, two), sylvan_xor(two, one)));
|
|
test_assert(testEqual(sylvan_xor(a, b), sylvan_ite(a, sylvan_not(b), b)));
|
|
|
|
// Test diff
|
|
test_assert(testEqual(sylvan_diff(a, b), sylvan_diff(a, b)));
|
|
test_assert(testEqual(sylvan_diff(a, b), sylvan_diff(a, sylvan_and(a, b))));
|
|
test_assert(testEqual(sylvan_diff(a, b), sylvan_and(a, sylvan_not(b))));
|
|
test_assert(testEqual(sylvan_diff(a, b), sylvan_ite(b, sylvan_false, a)));
|
|
test_assert(testEqual(sylvan_diff(one, two), sylvan_diff(one, two)));
|
|
test_assert(testEqual(sylvan_diff(one, two), sylvan_diff(one, sylvan_and(one, two))));
|
|
test_assert(testEqual(sylvan_diff(one, two), sylvan_and(one, sylvan_not(two))));
|
|
test_assert(testEqual(sylvan_diff(one, two), sylvan_ite(two, sylvan_false, one)));
|
|
|
|
// Test biimp
|
|
test_assert(testEqual(sylvan_biimp(a, b), sylvan_makenode(1, sylvan_not(b), b)));
|
|
test_assert(testEqual(sylvan_biimp(a, b), sylvan_biimp(b, a)));
|
|
test_assert(testEqual(sylvan_biimp(one, two), sylvan_biimp(two, one)));
|
|
|
|
// Test nand / and
|
|
test_assert(testEqual(sylvan_not(sylvan_and(a, b)), sylvan_nand(b, a)));
|
|
test_assert(testEqual(sylvan_not(sylvan_and(one, two)), sylvan_nand(two, one)));
|
|
|
|
// Test nor / or
|
|
test_assert(testEqual(sylvan_not(sylvan_or(a, b)), sylvan_nor(b, a)));
|
|
test_assert(testEqual(sylvan_not(sylvan_or(one, two)), sylvan_nor(two, one)));
|
|
|
|
// Test xor / biimp
|
|
test_assert(testEqual(sylvan_xor(a, b), sylvan_not(sylvan_biimp(b, a))));
|
|
test_assert(testEqual(sylvan_xor(one, two), sylvan_not(sylvan_biimp(two, one))));
|
|
|
|
// Test imp
|
|
test_assert(testEqual(sylvan_imp(a, b), sylvan_ite(a, b, sylvan_true)));
|
|
test_assert(testEqual(sylvan_imp(one, two), sylvan_ite(one, two, sylvan_true)));
|
|
test_assert(testEqual(sylvan_imp(one, two), sylvan_not(sylvan_diff(one, two))));
|
|
test_assert(testEqual(sylvan_invimp(one, two), sylvan_not(sylvan_less(one, two))));
|
|
test_assert(testEqual(sylvan_imp(a, b), sylvan_invimp(b, a)));
|
|
test_assert(testEqual(sylvan_imp(one, two), sylvan_invimp(two, one)));
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
test_relprod()
|
|
{
|
|
LACE_ME;
|
|
|
|
BDDVAR vars[] = {0,2,4};
|
|
BDDVAR all_vars[] = {0,1,2,3,4,5};
|
|
|
|
BDDSET vars_set = sylvan_set_fromarray(vars, 3);
|
|
BDDSET all_vars_set = sylvan_set_fromarray(all_vars, 6);
|
|
|
|
BDD s, t, next, prev;
|
|
BDD zeroes, ones;
|
|
|
|
// transition relation: 000 --> 111 and !000 --> 000
|
|
t = sylvan_false;
|
|
t = sylvan_union_cube(t, all_vars_set, ((uint8_t[]){0,1,0,1,0,1}));
|
|
t = sylvan_union_cube(t, all_vars_set, ((uint8_t[]){1,0,2,0,2,0}));
|
|
t = sylvan_union_cube(t, all_vars_set, ((uint8_t[]){2,0,1,0,2,0}));
|
|
t = sylvan_union_cube(t, all_vars_set, ((uint8_t[]){2,0,2,0,1,0}));
|
|
|
|
s = sylvan_cube(vars_set, (uint8_t[]){0,0,1});
|
|
zeroes = sylvan_cube(vars_set, (uint8_t[]){0,0,0});
|
|
ones = sylvan_cube(vars_set, (uint8_t[]){1,1,1});
|
|
|
|
next = sylvan_relnext(s, t, all_vars_set);
|
|
prev = sylvan_relprev(t, next, all_vars_set);
|
|
test_assert(next == zeroes);
|
|
test_assert(prev == sylvan_not(zeroes));
|
|
|
|
next = sylvan_relnext(next, t, all_vars_set);
|
|
prev = sylvan_relprev(t, next, all_vars_set);
|
|
test_assert(next == ones);
|
|
test_assert(prev == zeroes);
|
|
|
|
t = sylvan_cube(all_vars_set, (uint8_t[]){0,0,0,0,0,1});
|
|
test_assert(sylvan_relprev(t, s, all_vars_set) == zeroes);
|
|
test_assert(sylvan_relprev(t, sylvan_not(s), all_vars_set) == sylvan_false);
|
|
test_assert(sylvan_relnext(s, t, all_vars_set) == sylvan_false);
|
|
test_assert(sylvan_relnext(zeroes, t, all_vars_set) == s);
|
|
|
|
t = sylvan_cube(all_vars_set, (uint8_t[]){0,0,0,0,0,2});
|
|
test_assert(sylvan_relprev(t, s, all_vars_set) == zeroes);
|
|
test_assert(sylvan_relprev(t, zeroes, all_vars_set) == zeroes);
|
|
test_assert(sylvan_relnext(sylvan_not(zeroes), t, all_vars_set) == sylvan_false);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
test_compose()
|
|
{
|
|
LACE_ME;
|
|
|
|
BDD a = sylvan_ithvar(1);
|
|
BDD b = sylvan_ithvar(2);
|
|
|
|
BDD a_or_b = sylvan_or(a, b);
|
|
|
|
BDD one = make_random(3, 16);
|
|
BDD two = make_random(8, 24);
|
|
|
|
BDDMAP map = sylvan_map_empty();
|
|
|
|
map = sylvan_map_add(map, 1, one);
|
|
map = sylvan_map_add(map, 2, two);
|
|
|
|
test_assert(sylvan_map_key(map) == 1);
|
|
test_assert(sylvan_map_value(map) == one);
|
|
test_assert(sylvan_map_key(sylvan_map_next(map)) == 2);
|
|
test_assert(sylvan_map_value(sylvan_map_next(map)) == two);
|
|
|
|
test_assert(testEqual(one, sylvan_compose(a, map)));
|
|
test_assert(testEqual(two, sylvan_compose(b, map)));
|
|
|
|
test_assert(testEqual(sylvan_or(one, two), sylvan_compose(a_or_b, map)));
|
|
|
|
map = sylvan_map_add(map, 2, one);
|
|
test_assert(testEqual(sylvan_compose(a_or_b, map), one));
|
|
|
|
map = sylvan_map_add(map, 1, two);
|
|
test_assert(testEqual(sylvan_or(one, two), sylvan_compose(a_or_b, map)));
|
|
|
|
test_assert(testEqual(sylvan_and(one, two), sylvan_compose(sylvan_and(a, b), map)));
|
|
|
|
// test that composing [0:=true] on "0" yields true
|
|
map = sylvan_map_add(sylvan_map_empty(), 1, sylvan_true);
|
|
test_assert(testEqual(sylvan_compose(a, map), sylvan_true));
|
|
|
|
// test that composing [0:=false] on "0" yields false
|
|
map = sylvan_map_add(sylvan_map_empty(), 1, sylvan_false);
|
|
test_assert(testEqual(sylvan_compose(a, map), sylvan_false));
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
test_ldd()
|
|
{
|
|
// very basic testing of makenode
|
|
for (int i=0; i<10; i++) {
|
|
uint32_t value = rng(0, 100);
|
|
MDD m = lddmc_makenode(value, lddmc_true, lddmc_false);
|
|
test_assert(lddmc_getvalue(m) == value);
|
|
test_assert(lddmc_getdown(m) == lddmc_true);
|
|
test_assert(lddmc_getright(m) == lddmc_false);
|
|
test_assert(lddmc_iscopy(m) == 0);
|
|
test_assert(lddmc_follow(m, value) == lddmc_true);
|
|
for (int j=0; j<100; j++) {
|
|
uint32_t other_value = rng(0, 100);
|
|
if (value != other_value) test_assert(lddmc_follow(m, other_value) == lddmc_false);
|
|
}
|
|
}
|
|
|
|
// test handling of the copy node by primitives
|
|
MDD m = lddmc_make_copynode(lddmc_true, lddmc_false);
|
|
test_assert(lddmc_iscopy(m) == 1);
|
|
test_assert(lddmc_getvalue(m) == 0);
|
|
test_assert(lddmc_getdown(m) == lddmc_true);
|
|
test_assert(lddmc_getright(m) == lddmc_false);
|
|
m = lddmc_extendnode(m, 0, lddmc_true);
|
|
test_assert(lddmc_iscopy(m) == 1);
|
|
test_assert(lddmc_getvalue(m) == 0);
|
|
test_assert(lddmc_getdown(m) == lddmc_true);
|
|
test_assert(lddmc_getright(m) != lddmc_false);
|
|
test_assert(lddmc_follow(m, 0) == lddmc_true);
|
|
test_assert(lddmc_getvalue(lddmc_getright(m)) == 0);
|
|
test_assert(lddmc_iscopy(lddmc_getright(m)) == 0);
|
|
test_assert(lddmc_makenode(0, lddmc_true, lddmc_false) == lddmc_getright(m));
|
|
|
|
LACE_ME;
|
|
// test union_cube
|
|
for (int i=0; i<100; i++) {
|
|
int depth = rng(1, 6);
|
|
int elements = rng(1, 30);
|
|
m = make_random_ldd_set(depth, 10, elements);
|
|
assert(m != lddmc_true);
|
|
assert(m != lddmc_false);
|
|
assert(lddmc_satcount(m) <= elements);
|
|
assert(lddmc_satcount(m) >= 1);
|
|
}
|
|
|
|
// test simply transition relation
|
|
{
|
|
MDD states, rel, meta, expected;
|
|
|
|
// relation: (0,0) to (1,1)
|
|
rel = lddmc_cube((uint32_t[]){0,1,0,1}, 4);
|
|
test_assert(lddmc_satcount(rel) == 1);
|
|
// relation: (0,0) to (2,2)
|
|
rel = lddmc_union_cube(rel, (uint32_t[]){0,2,0,2}, 4);
|
|
test_assert(lddmc_satcount(rel) == 2);
|
|
// meta: read write read write
|
|
meta = lddmc_cube((uint32_t[]){1,2,1,2}, 4);
|
|
test_assert(lddmc_satcount(meta) == 1);
|
|
// initial state: (0,0)
|
|
states = lddmc_cube((uint32_t[]){0,0}, 2);
|
|
test_assert(lddmc_satcount(states) == 1);
|
|
// relprod should give two states
|
|
states = lddmc_relprod(states, rel, meta);
|
|
test_assert(lddmc_satcount(states) == 2);
|
|
// relprod should give states (1,1) and (2,2)
|
|
expected = lddmc_cube((uint32_t[]){1,1}, 2);
|
|
expected = lddmc_union_cube(expected, (uint32_t[]){2,2}, 2);
|
|
test_assert(states == expected);
|
|
|
|
// now test relprod union on the simple example
|
|
states = lddmc_cube((uint32_t[]){0,0}, 2);
|
|
states = lddmc_relprod_union(states, rel, meta, states);
|
|
test_assert(lddmc_satcount(states) == 3);
|
|
test_assert(states == lddmc_union(states, expected));
|
|
|
|
// now create transition (1,1) --> (1,1) (using copy nodes)
|
|
rel = lddmc_cube_copy((uint32_t[]){1,0,1,0}, (int[]){0,1,0,1}, 4);
|
|
states = lddmc_relprod(states, rel, meta);
|
|
// the result should be just state (1,1)
|
|
test_assert(states == lddmc_cube((uint32_t[]){1,1}, 2));
|
|
|
|
MDD statezero = lddmc_cube((uint32_t[]){0,0}, 2);
|
|
states = lddmc_union_cube(statezero, (uint32_t[]){1,1}, 2);
|
|
test_assert(lddmc_relprod_union(states, rel, meta, statezero) == states);
|
|
|
|
// now create transition (*,*) --> (*,*) (copy nodes)
|
|
rel = lddmc_cube_copy((uint32_t[]){0,0}, (int[]){1,1}, 2);
|
|
meta = lddmc_cube((uint32_t[]){4,4}, 2);
|
|
states = make_random_ldd_set(2, 10, 10);
|
|
MDD states2 = make_random_ldd_set(2, 10, 10);
|
|
test_assert(lddmc_union(states, states2) == lddmc_relprod_union(states, rel, meta, states2));
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int runtests()
|
|
{
|
|
// we are not testing garbage collection
|
|
sylvan_gc_disable();
|
|
|
|
if (test_cache()) return 1;
|
|
if (test_bdd()) return 1;
|
|
for (int j=0;j<10;j++) if (test_cube()) return 1;
|
|
for (int j=0;j<10;j++) if (test_relprod()) return 1;
|
|
for (int j=0;j<10;j++) if (test_compose()) return 1;
|
|
for (int j=0;j<10;j++) if (test_operators()) return 1;
|
|
|
|
if (test_ldd()) return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int main()
|
|
{
|
|
// Standard Lace initialization with 1 worker
|
|
lace_init(1, 0);
|
|
lace_startup(0, NULL, NULL);
|
|
|
|
// Simple Sylvan initialization, also initialize BDD, MTBDD and LDD support
|
|
sylvan_set_sizes(1LL<<20, 1LL<<20, 1LL<<16, 1LL<<16);
|
|
sylvan_init_package();
|
|
sylvan_init_bdd();
|
|
sylvan_init_mtbdd();
|
|
sylvan_init_ldd();
|
|
|
|
int res = runtests();
|
|
|
|
sylvan_quit();
|
|
lace_exit();
|
|
|
|
return res;
|
|
}
|