static void rel_load(FILE* f, vrel_t rel) { if (rel->bdd) sylvan_deref(rel->bdd); if (rel->vec_to_bddvar) RTfree(rel->vec_to_bddvar); if (rel->prime_vec_to_bddvar) RTfree(rel->prime_vec_to_bddvar); if (rel->variables) sylvan_deref(rel->variables); if (rel->prime_variables) sylvan_deref(rel->prime_variables); if (rel->all_variables) sylvan_deref(rel->all_variables); sylvan_serialize_fromfile(f); size_t bdd; fread(&bdd, sizeof(size_t), 1, f); rel->bdd = sylvan_ref(sylvan_serialize_get_reversed(bdd)); fread(&rel->vector_size, sizeof(size_t), 1, f); rel->vec_to_bddvar = (BDDVAR*)RTmalloc(sizeof(BDDVAR) * fddbits * rel->vector_size); rel->prime_vec_to_bddvar = (BDDVAR*)RTmalloc(sizeof(BDDVAR) * fddbits * rel->vector_size); fread(rel->vec_to_bddvar, sizeof(BDDVAR), rel->vector_size*fddbits, f); fread(rel->prime_vec_to_bddvar, sizeof(BDDVAR), rel->vector_size*fddbits, f); sylvan_gc_disable(); LACE_ME; rel->variables = sylvan_ref(sylvan_set_fromarray(rel->vec_to_bddvar, fddbits * rel->vector_size)); rel->prime_variables = sylvan_ref(sylvan_set_fromarray(rel->prime_vec_to_bddvar, fddbits * rel->vector_size)); rel->all_variables = sylvan_ref(sylvan_set_addall(rel->prime_variables, rel->variables)); sylvan_gc_enable(); }
/** * Create a "relation" (Dom x Dom) * 0 < k <= dom->shared.size * The integers in proj, a k-length array, are indices of the * state vector. */ static vrel_t rel_create(vdom_t dom, int k, int* proj) { LACE_ME; sylvan_gc_disable(); vrel_t rel = (vrel_t)RTmalloc(sizeof(struct vector_relation)); rel->dom = dom; rel->bdd = sylvan_false; // Initially, empty. // Relations are always projections. assert (k >= 0 && k<=dom->shared.size); rel->vector_size = k; rel->vec_to_bddvar = (BDDVAR*)RTmalloc(sizeof(BDDVAR) * fddbits * rel->vector_size); rel->prime_vec_to_bddvar = (BDDVAR*)RTmalloc(sizeof(BDDVAR) * fddbits * rel->vector_size); for (int i=0; i<k; i++) { for (int j=0; j<fddbits; j++) { rel->vec_to_bddvar[i*fddbits + j] = dom->vec_to_bddvar[proj[i]*fddbits + j]; rel->prime_vec_to_bddvar[i*fddbits + j] = dom->prime_vec_to_bddvar[proj[i]*fddbits + j]; } } sylvan_gc_disable(); rel->variables = sylvan_ref(sylvan_set_fromarray(rel->vec_to_bddvar, fddbits * rel->vector_size)); rel->prime_variables = sylvan_ref(sylvan_set_fromarray(rel->prime_vec_to_bddvar, fddbits * rel->vector_size)); rel->all_variables = sylvan_ref(sylvan_set_addall(rel->prime_variables, rel->variables)); sylvan_gc_enable(); return rel; }
static void init_universe(vdom_t dom) { LACE_ME; int n = dom->shared.size; sylvan_gc_disable(); dom->universe = sylvan_ref(sylvan_set_fromarray(dom->vec_to_bddvar, fddbits * n)); dom->prime_universe = sylvan_ref(sylvan_set_fromarray(dom->prime_vec_to_bddvar, fddbits * n)); sylvan_gc_enable(); }
/** * This means: create a new BDD set in the domain dom * dom = my domain (just copy) * k is the number of integers in proj * proj is a list of indices of the state vector in the projection */ static vset_t set_create(vdom_t dom, int k, int* proj) { vset_t set = (vset_t)RTmalloc(sizeof(struct vector_set)); LACE_ME; set->dom = dom; set->bdd = sylvan_false; // Initialize with an empty BDD if (k>=0 && k<dom->shared.size) { // We are creating a projection set->vector_size = k; set->vec_to_bddvar = (BDDVAR*)RTmalloc(sizeof(BDDVAR) * fddbits * set->vector_size); for (int i=0; i<k; i++) { for (int j=0; j<fddbits; j++) { set->vec_to_bddvar[i*fddbits + j] = dom->vec_to_bddvar[proj[i]*fddbits + j]; } } } else { // Use all variables set->vector_size = dom->shared.size; set->vec_to_bddvar = (BDDVAR*)RTmalloc(sizeof(BDDVAR) * fddbits * set->vector_size); memcpy(set->vec_to_bddvar, dom->vec_to_bddvar, sizeof(BDDVAR) * fddbits * set->vector_size); } sylvan_gc_disable(); set->variables = sylvan_ref(sylvan_set_fromarray(set->vec_to_bddvar, fddbits * set->vector_size)); set->projection = sylvan_ref(sylvan_set_removeall(dom->universe, set->variables)); sylvan_gc_enable(); return set; }
/** * Returns the BDD corresponding to state e according to the projection of set. * Order: [0]<[1]<[n] and hi < lo */ static BDD state_to_bdd(const int* e, size_t vec_length, BDDVAR* vec_to_bddvar, BDD projection) { LACE_ME; check_state(e, vec_length); size_t varcount = vec_length * fddbits; char* cube = (char*)alloca(varcount*sizeof(char)); memset(cube, 0, varcount*sizeof(char)); size_t i; int j; for (i=0;i<vec_length;i++) { for (j=0;j<fddbits;j++) { if (e[i] & (1<<(fddbits-j-1))) cube[i*fddbits+j] = 1; } } // check if in right order for (i=0;i<varcount-1;i++) assert(vec_to_bddvar[i]<vec_to_bddvar[i+1]); BDDSET meta = sylvan_set_fromarray(vec_to_bddvar, varcount); BDD bdd = sylvan_ref(sylvan_cube(meta, cube)); BDD proj = sylvan_ref(sylvan_exists(bdd, projection)); sylvan_deref(bdd); return proj; }
static vset_t set_load(FILE* f, vdom_t dom) { vset_t set = (vset_t)RTmalloc(sizeof(struct vector_set)); set->dom = dom; sylvan_serialize_fromfile(f); size_t bdd; fread(&bdd, sizeof(size_t), 1, f); set->bdd = sylvan_ref(sylvan_serialize_get_reversed(bdd)); fread(&set->vector_size, sizeof(size_t), 1, f); set->vec_to_bddvar = (BDDVAR*)RTmalloc(sizeof(BDDVAR) * fddbits * set->vector_size); fread(set->vec_to_bddvar, sizeof(BDDVAR), fddbits * set->vector_size, f); LACE_ME; sylvan_gc_disable(); set->variables = sylvan_ref(sylvan_set_fromarray(set->vec_to_bddvar, fddbits * set->vector_size)); set->projection = sylvan_ref(sylvan_set_removeall(dom->universe, set->variables)); sylvan_gc_enable(); return set; }
JNIEXPORT jobject JNICALL Java_jsylvan_MCFile_fromFile(JNIEnv *env, jclass cl, jstring filename) { const char *fname = (*env)->GetStringUTFChars(env, filename, 0); FILE *f = fopen(fname, "r"); if (f == NULL) { // TODO: exception Abort("Cannot open file '%s'!\n", fname); } (*env)->ReleaseStringUTFChars(env, filename, fname); LACE_ME; /* Read domain data */ int vectorsize; if (fread(&vectorsize, sizeof(int), 1, f) != 1) Abort("Invalid input file!\n"); int statebits[vectorsize]; if (fread(statebits, sizeof(int), vectorsize, f) != (size_t)vectorsize) Abort("Invalid input file!\n"); int actionbits; if (fread(&actionbits, sizeof(int), 1, f) != 1) Abort("Invalid input file!\n"); int totalbits = 0; for (int i=0; i<vectorsize; i++) totalbits += statebits[i]; printf("Read file for %d ints, %d bits per state\n", vectorsize, totalbits); // Read initial state { int k; if (fread(&k, sizeof(int), 1, f) != 1) Abort("Invalid input file!\n"); if (k != -1) Abort("Unsupported input file!\n"); } BDD initial; if (mtbdd_reader_frombinary(f, &initial, 1) != 0) Abort("Invalid input file!\n"); mtbdd_ref(initial); // Read number of transitions int numberOfGroups; if (fread(&numberOfGroups, sizeof(int), 1, f) != 1) Abort("Invalid input file!\n"); printf("There are %d transition groups.\n", numberOfGroups); // Read transition projections BDD domains[numberOfGroups]; for (int z=0; z<numberOfGroups; z++) { int r_k, w_k; if (fread(&r_k, sizeof(int), 1, f) != 1) Abort("Invalid file format."); if (fread(&w_k, sizeof(int), 1, f) != 1) Abort("Invalid file format."); int r_proj[r_k]; int w_proj[w_k]; if (fread(r_proj, sizeof(int), r_k, f) != (size_t)r_k) Abort("Invalid file format."); if (fread(w_proj, sizeof(int), w_k, f) != (size_t)w_k) Abort("Invalid file format."); /* Compute a_proj the union of r_proj and w_proj, and a_k the length of a_proj */ int a_proj[r_k+w_k]; int r_i = 0, w_i = 0, a_i = 0; for (;r_i < r_k || w_i < w_k;) { if (r_i < r_k && w_i < w_k) { if (r_proj[r_i] < w_proj[w_i]) { a_proj[a_i++] = r_proj[r_i++]; } else if (r_proj[r_i] > w_proj[w_i]) { a_proj[a_i++] = w_proj[w_i++]; } else /* r_proj[r_i] == w_proj[w_i] */ { a_proj[a_i++] = w_proj[w_i++]; r_i++; } } else if (r_i < r_k) { a_proj[a_i++] = r_proj[r_i++]; } else if (w_i < w_k) { a_proj[a_i++] = w_proj[w_i++]; } } const int a_k = a_i; /* Compute all_variables, which are all variables the transition relation is defined on */ uint32_t all_vars[totalbits * 2]; uint32_t curvar = 0; // start with variable 0 int i=0, j=0, n=0; for (; i<vectorsize && j<a_k; i++) { if (i == a_proj[j]) { for (int k=0; k<statebits[i]; k++) { all_vars[n++] = curvar; all_vars[n++] = curvar + 1; curvar += 2; } j++; } else { curvar += 2 * statebits[i]; } } domains[z] = sylvan_set_fromarray(all_vars, n); mtbdd_ref(domains[z]); } // Read transitions BDD next[numberOfGroups]; for (int z=0; z<numberOfGroups; z++) { if (mtbdd_reader_frombinary(f, &next[z], 1) != 0) Abort("Invalid input file!\n"); mtbdd_ref(next[z]); } fclose(f); // Create domain int dom_arr[totalbits]; for (int k=0; k<totalbits; k++) { dom_arr[k] = 2*k; } BDD domain = sylvan_set_fromarray(dom_arr, totalbits); mtbdd_ref(domain); // Convert everything to a nice object jmethodID constructor = (*env)->GetMethodID(env, cl, "<init>", "()V"); jobject result = (*env)->NewObject(env, cl, constructor); jfieldID fid; jlongArray arr; jlong *dest; // set vectorSize field fid = (*env)->GetFieldID(env, cl, "vectorSize", "J"); (*env)->SetLongField(env, result, fid, (jlong)vectorsize); // set totalBits field fid = (*env)->GetFieldID(env, cl, "totalBits", "J"); (*env)->SetLongField(env, result, fid, (jlong)totalbits); // set initial field fid = (*env)->GetFieldID(env, cl, "initial", "J"); (*env)->SetLongField(env, result, fid, (jlong)initial); // set domain field fid = (*env)->GetFieldID(env, cl, "domain", "J"); (*env)->SetLongField(env, result, fid, (jlong)domain); // set relations field arr = (*env)->NewLongArray(env, numberOfGroups); dest = (*env)->GetLongArrayElements(env, arr, 0); for (int i=0; i<numberOfGroups; i++) dest[i] = next[i]; (*env)->ReleaseLongArrayElements(env, arr, dest, 0); fid = (*env)->GetFieldID(env, cl, "relations", "[J"); (*env)->SetObjectField(env, result, fid, arr); // set domains array arr = (*env)->NewLongArray(env, numberOfGroups); dest = (*env)->GetLongArrayElements(env, arr, 0); for (int i=0; i<numberOfGroups; i++) dest[i] = domains[i]; (*env)->ReleaseLongArrayElements(env, arr, dest, 0); fid = (*env)->GetFieldID(env, cl, "relation_domains", "[J"); (*env)->SetObjectField(env, result, fid, arr); return result; }