|  |  | @ -213,7 +213,7 @@ TASK_IMPL_2(MTBDD, mtbdd_op_less, MTBDD*, pa, MTBDD*, pb) | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | /** | 
			
		
	
		
			
				
					|  |  |  |  * Binary operation Equals (for MTBDDs of same type) | 
			
		
	
		
			
				
					|  |  |  |  * Binary operation Less or Equals (for MTBDDs of same type) | 
			
		
	
		
			
				
					|  |  |  |  * Only for MTBDDs where either all leaves are Boolean, or Integer, or Double. | 
			
		
	
		
			
				
					|  |  |  |  * For Integer/Double MTBDD, if either operand is mtbdd_false (not defined), | 
			
		
	
		
			
				
					|  |  |  |  * then the result is mtbdd_false (i.e. not defined). | 
			
		
	
	
		
			
				
					|  |  | @ -261,6 +261,55 @@ TASK_IMPL_2(MTBDD, mtbdd_op_less_or_equal, MTBDD*, pa, MTBDD*, pb) | 
			
		
	
		
			
				
					|  |  |  |     return mtbdd_invalid; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | /** | 
			
		
	
		
			
				
					|  |  |  |  * Binary operation Greater or Equals (for MTBDDs of same type) | 
			
		
	
		
			
				
					|  |  |  |  * Only for MTBDDs where either all leaves are Boolean, or Integer, or Double. | 
			
		
	
		
			
				
					|  |  |  |  * For Integer/Double MTBDD, if either operand is mtbdd_false (not defined), | 
			
		
	
		
			
				
					|  |  |  |  * then the result is mtbdd_false (i.e. not defined). | 
			
		
	
		
			
				
					|  |  |  |  */ | 
			
		
	
		
			
				
					|  |  |  | TASK_IMPL_2(MTBDD, mtbdd_op_greater_or_equal, MTBDD*, pa, MTBDD*, pb) | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |     MTBDD a = *pa, b = *pb; | 
			
		
	
		
			
				
					|  |  |  |     if (a == mtbdd_false && b == mtbdd_false) return mtbdd_true; | 
			
		
	
		
			
				
					|  |  |  |     if (a == mtbdd_true && b == mtbdd_true) return mtbdd_true; | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     mtbddnode_t na = MTBDD_GETNODE(a); | 
			
		
	
		
			
				
					|  |  |  |     mtbddnode_t nb = MTBDD_GETNODE(b); | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     if (mtbddnode_isleaf(na) && mtbddnode_isleaf(nb)) { | 
			
		
	
		
			
				
					|  |  |  |         uint64_t val_a = mtbddnode_getvalue(na); | 
			
		
	
		
			
				
					|  |  |  |         uint64_t val_b = mtbddnode_getvalue(nb); | 
			
		
	
		
			
				
					|  |  |  |         if (mtbddnode_gettype(na) == 0 && mtbddnode_gettype(nb) == 0) { | 
			
		
	
		
			
				
					|  |  |  |             int64_t va = *(int64_t*)(&val_a); | 
			
		
	
		
			
				
					|  |  |  |             int64_t vb = *(int64_t*)(&val_b); | 
			
		
	
		
			
				
					|  |  |  |             return va >= vb ? mtbdd_true : mtbdd_false; | 
			
		
	
		
			
				
					|  |  |  |         } else if (mtbddnode_gettype(na) == 1 && mtbddnode_gettype(nb) == 1) { | 
			
		
	
		
			
				
					|  |  |  |             // both double | 
			
		
	
		
			
				
					|  |  |  |             double vval_a = *(double*)&val_a; | 
			
		
	
		
			
				
					|  |  |  |             double vval_b = *(double*)&val_b; | 
			
		
	
		
			
				
					|  |  |  |             if (vval_a >= vval_b) return mtbdd_true; | 
			
		
	
		
			
				
					|  |  |  |             return mtbdd_false; | 
			
		
	
		
			
				
					|  |  |  |         } else if (mtbddnode_gettype(na) == 2 && mtbddnode_gettype(nb) == 2) { | 
			
		
	
		
			
				
					|  |  |  |             // both fraction | 
			
		
	
		
			
				
					|  |  |  |             uint64_t nom_a = val_a>>32; | 
			
		
	
		
			
				
					|  |  |  |             uint64_t nom_b = val_b>>32; | 
			
		
	
		
			
				
					|  |  |  |             uint64_t denom_a = val_a&0xffffffff; | 
			
		
	
		
			
				
					|  |  |  |             uint64_t denom_b = val_b&0xffffffff; | 
			
		
	
		
			
				
					|  |  |  |             nom_a *= denom_b; | 
			
		
	
		
			
				
					|  |  |  |             nom_b *= denom_a; | 
			
		
	
		
			
				
					|  |  |  |             return nom_a >= nom_b ? mtbdd_true : mtbdd_false; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  | #if defined(SYLVAN_HAVE_CARL) || defined(STORM_HAVE_CARL) | 
			
		
	
		
			
				
					|  |  |  | 		else if (mtbddnode_gettype(na) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID && mtbddnode_gettype(nb) == SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID) { | 
			
		
	
		
			
				
					|  |  |  | 			printf("ERROR mtbdd_op_greater_or_equal type SYLVAN_STORM_RATIONAL_FUNCTION_TYPE_ID"); | 
			
		
	
		
			
				
					|  |  |  | 			assert(0); | 
			
		
	
		
			
				
					|  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  | #endif | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     return mtbdd_invalid; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | /** | 
			
		
	
		
			
				
					|  |  |  |  * Binary operation Pow (for MTBDDs of same type) | 
			
		
	
		
			
				
					|  |  |  |  * Only for MTBDDs where either all leaves are Double. | 
			
		
	
	
		
			
				
					|  |  | @ -629,54 +678,81 @@ TASK_IMPL_2(MTBDD, mtbdd_op_complement, MTBDD, a, size_t, k) | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | TASK_IMPL_3(BDD, mtbdd_minExistsRepresentative, MTBDD, a, BDD, variables, BDDVAR, prev_level) { | 
			
		
	
		
			
				
					|  |  |  | 	BDD zero = sylvan_false; | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  | 	/* Maybe perform garbage collection */ | 
			
		
	
		
			
				
					|  |  |  |     sylvan_gc_test(); | 
			
		
	
		
			
				
					|  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  |     /* Cube is guaranteed to be a cube at this point. */ | 
			
		
	
		
			
				
					|  |  |  | 	printf("Entered method.\n"); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	if (sylvan_set_isempty(variables)) { | 
			
		
	
		
			
				
					|  |  |  | 		return sylvan_true; | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	/* Cube is guaranteed to be a cube at this point. */ | 
			
		
	
		
			
				
					|  |  |  |     if (mtbdd_isleaf(a)) { | 
			
		
	
		
			
				
					|  |  |  | 		printf("is leaf\n"); | 
			
		
	
		
			
				
					|  |  |  |         if (sylvan_set_isempty(variables)) { | 
			
		
	
		
			
				
					|  |  |  | 			printf("set is empty\n"); | 
			
		
	
		
			
				
					|  |  |  |             return sylvan_true; // FIXME? | 
			
		
	
		
			
				
					|  |  |  |         } else { | 
			
		
	
		
			
				
					|  |  |  | 			printf("have variables.\n"); | 
			
		
	
		
			
				
					|  |  |  | 			BDD _v = sylvan_set_next(variables); | 
			
		
	
		
			
				
					|  |  |  | 			BDD res = CALL(mtbdd_minExistsRepresentative, a, _v, prev_level); | 
			
		
	
		
			
				
					|  |  |  | 			if (res == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  | 				return sylvan_invalid; | 
			
		
	
		
			
				
					|  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  | 			sylvan_ref(res); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 			BDD res1 = sylvan_ite(sylvan_ithvar(bddnode_getvariable(BDD_GETNODE(variables))), sylvan_false, res); | 
			
		
	
		
			
				
					|  |  |  | 			if (res1 == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  | 				sylvan_deref(res); | 
			
		
	
		
			
				
					|  |  |  | 				return sylvan_invalid; | 
			
		
	
		
			
				
					|  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  | 		BDD _v = sylvan_set_next(variables); | 
			
		
	
		
			
				
					|  |  |  | 		BDD res = CALL(mtbdd_minExistsRepresentative, a, _v, prev_level); | 
			
		
	
		
			
				
					|  |  |  | 		if (res == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  | 			return sylvan_invalid; | 
			
		
	
		
			
				
					|  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  | 		sylvan_ref(res); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 		BDD res1 = sylvan_not(sylvan_ite(sylvan_ithvar(bddnode_getvariable(BDD_GETNODE(variables))), sylvan_true, sylvan_not(res))); | 
			
		
	
		
			
				
					|  |  |  | 		if (res1 == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  | 			sylvan_deref(res); | 
			
		
	
		
			
				
					|  |  |  | 			return res1; | 
			
		
	
		
			
				
					|  |  |  | 			return sylvan_invalid; | 
			
		
	
		
			
				
					|  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  | 		sylvan_deref(res); | 
			
		
	
		
			
				
					|  |  |  | 		return res1; | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  | 	mtbddnode_t na = MTBDD_GETNODE(a); | 
			
		
	
		
			
				
					|  |  |  | 	uint32_t va = mtbddnode_getvariable(na); | 
			
		
	
		
			
				
					|  |  |  | 	bddnode_t nv = BDD_GETNODE(variables); | 
			
		
	
		
			
				
					|  |  |  | 	BDDVAR vv = bddnode_getvariable(nv); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     /* Abstract a variable that does not appear in a. */ | 
			
		
	
		
			
				
					|  |  |  |     if (va > vv) { | 
			
		
	
		
			
				
					|  |  |  | 		BDD _v = sylvan_set_next(variables); | 
			
		
	
		
			
				
					|  |  |  |         BDD res = CALL(mtbdd_minExistsRepresentative, a, _v, va); | 
			
		
	
		
			
				
					|  |  |  |         if (res == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  |             return sylvan_invalid; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |     } else if (sylvan_set_isempty(variables)) { | 
			
		
	
		
			
				
					|  |  |  | 		mtbddnode_t na = MTBDD_GETNODE(a); | 
			
		
	
		
			
				
					|  |  |  | 		uint32_t va = mtbddnode_getvariable(na); | 
			
		
	
		
			
				
					|  |  |  | 		MTBDD E = mtbdd_getlow(a); | 
			
		
	
		
			
				
					|  |  |  | 		MTBDD T = mtbdd_gethigh(a); | 
			
		
	
		
			
				
					|  |  |  | 		BDD res1 = CALL(mtbdd_minExistsRepresentative, E, variables, va); | 
			
		
	
		
			
				
					|  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |         // Fill in the missing variables to make representative unique. | 
			
		
	
		
			
				
					|  |  |  |         sylvan_ref(res); | 
			
		
	
		
			
				
					|  |  |  |         BDD res1 = sylvan_ite(sylvan_ithvar(vv), sylvan_false, res); | 
			
		
	
		
			
				
					|  |  |  |         if (res1 == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(res); | 
			
		
	
		
			
				
					|  |  |  |             return sylvan_invalid; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         sylvan_deref(res); | 
			
		
	
		
			
				
					|  |  |  |        	return res1; | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  | 	/* TODO: Caching here. */ | 
			
		
	
		
			
				
					|  |  |  |     /*if ((res = cuddCacheLookup2(manager, Cudd_addMinAbstractRepresentative, f, cube)) != NULL) { | 
			
		
	
		
			
				
					|  |  |  |         return(res); | 
			
		
	
		
			
				
					|  |  |  |     }*/ | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     MTBDD E = mtbdd_getlow(a); | 
			
		
	
		
			
				
					|  |  |  |     MTBDD T = mtbdd_gethigh(a); | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     /* If the two indices are the same, so are their levels. */ | 
			
		
	
		
			
				
					|  |  |  |     if (va == vv) { | 
			
		
	
		
			
				
					|  |  |  | 		BDD _v = sylvan_set_next(variables); | 
			
		
	
		
			
				
					|  |  |  |         BDD res1 = CALL(mtbdd_minExistsRepresentative, E, _v, va); | 
			
		
	
		
			
				
					|  |  |  |         if (res1 == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  |             return sylvan_invalid; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         sylvan_ref(res1); | 
			
		
	
		
			
				
					|  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |         BDD res2 = CALL(mtbdd_minExistsRepresentative, T, variables, va); | 
			
		
	
		
			
				
					|  |  |  |         BDD res2 = CALL(mtbdd_minExistsRepresentative, T, _v, va); | 
			
		
	
		
			
				
					|  |  |  |         if (res2 == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(res1); | 
			
		
	
		
			
				
					|  |  |  |             return sylvan_invalid; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         sylvan_ref(res2); | 
			
		
	
		
			
				
					|  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |         MTBDD left = mtbdd_abstract_min(E, variables); | 
			
		
	
		
			
				
					|  |  |  |         MTBDD left = mtbdd_abstract_min(E, _v); | 
			
		
	
		
			
				
					|  |  |  |         if (left == mtbdd_invalid) { | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(res1); | 
			
		
	
		
			
				
					|  |  |  | 			sylvan_deref(res2); | 
			
		
	
	
		
			
				
					|  |  | @ -684,7 +760,7 @@ TASK_IMPL_3(BDD, mtbdd_minExistsRepresentative, MTBDD, a, BDD, variables, BDDVAR | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         mtbdd_ref(left); | 
			
		
	
		
			
				
					|  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |         MTBDD right = mtbdd_abstract_min(T, variables); | 
			
		
	
		
			
				
					|  |  |  |         MTBDD right = mtbdd_abstract_min(T, _v); | 
			
		
	
		
			
				
					|  |  |  |         if (right == mtbdd_invalid) { | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(res1); | 
			
		
	
		
			
				
					|  |  |  | 			sylvan_deref(res2); | 
			
		
	
	
		
			
				
					|  |  | @ -706,7 +782,7 @@ TASK_IMPL_3(BDD, mtbdd_minExistsRepresentative, MTBDD, a, BDD, variables, BDDVAR | 
			
		
	
		
			
				
					|  |  |  |         mtbdd_deref(left); | 
			
		
	
		
			
				
					|  |  |  | 		mtbdd_deref(right); | 
			
		
	
		
			
				
					|  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |         BDD res1Inf = sylvan_ite(tmp, res1, zero); | 
			
		
	
		
			
				
					|  |  |  |         BDD res1Inf = sylvan_ite(tmp, res1, sylvan_false); | 
			
		
	
		
			
				
					|  |  |  |         if (res1Inf == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(res1); | 
			
		
	
		
			
				
					|  |  |  | 			sylvan_deref(res2); | 
			
		
	
	
		
			
				
					|  |  | @ -715,30 +791,19 @@ TASK_IMPL_3(BDD, mtbdd_minExistsRepresentative, MTBDD, a, BDD, variables, BDDVAR | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         sylvan_ref(res1Inf); | 
			
		
	
		
			
				
					|  |  |  |         sylvan_deref(res1); | 
			
		
	
		
			
				
					|  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |         BDD tmp2 = sylvan_not(tmp); | 
			
		
	
		
			
				
					|  |  |  |         if (tmp2 == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  | 			sylvan_deref(res2); | 
			
		
	
		
			
				
					|  |  |  | 			mtbdd_deref(left); | 
			
		
	
		
			
				
					|  |  |  | 			mtbdd_deref(right); | 
			
		
	
		
			
				
					|  |  |  | 			sylvan_deref(tmp); | 
			
		
	
		
			
				
					|  |  |  |             return sylvan_invalid; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         sylvan_ref(tmp2); | 
			
		
	
		
			
				
					|  |  |  |         sylvan_deref(tmp); | 
			
		
	
		
			
				
					|  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |         BDD res2Inf = sylvan_ite(tmp2, res2, zero); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         BDD res2Inf = sylvan_ite(tmp, sylvan_false, res2); | 
			
		
	
		
			
				
					|  |  |  |         if (res2Inf == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(res2); | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(res1Inf); | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(tmp2); | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(tmp); | 
			
		
	
		
			
				
					|  |  |  |             return sylvan_invalid; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         sylvan_ref(res2Inf); | 
			
		
	
		
			
				
					|  |  |  |         sylvan_deref(res2); | 
			
		
	
		
			
				
					|  |  |  |         sylvan_deref(tmp2); | 
			
		
	
		
			
				
					|  |  |  |         sylvan_deref(tmp); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         BDD res = (res1Inf == res2Inf) ? sylvan_ite(sylvan_ithvar(va), zero, res1Inf) : sylvan_ite(sylvan_ithvar(va), res2Inf, res1Inf); | 
			
		
	
		
			
				
					|  |  |  |         BDD res = (res1Inf == res2Inf) ? sylvan_ite(sylvan_ithvar(va), sylvan_false, res1Inf) : sylvan_ite(sylvan_ithvar(va), res2Inf, res1Inf); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         if (res == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(res1Inf); | 
			
		
	
	
		
			
				
					|  |  | @ -754,7 +819,59 @@ TASK_IMPL_3(BDD, mtbdd_minExistsRepresentative, MTBDD, a, BDD, variables, BDDVAR | 
			
		
	
		
			
				
					|  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |         sylvan_deref(res); | 
			
		
	
		
			
				
					|  |  |  |         return res; | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |     else { /* if (va < vv) */ | 
			
		
	
		
			
				
					|  |  |  | 		BDD res1 = CALL(mtbdd_minExistsRepresentative, E, variables, va); | 
			
		
	
		
			
				
					|  |  |  |         if (res1 == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  | 			return sylvan_invalid; | 
			
		
	
		
			
				
					|  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |         sylvan_ref(res1); | 
			
		
	
		
			
				
					|  |  |  |         BDD res2 = CALL(mtbdd_minExistsRepresentative, T, variables, va); | 
			
		
	
		
			
				
					|  |  |  |         if (res2 == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(res1); | 
			
		
	
		
			
				
					|  |  |  |             return sylvan_invalid; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         sylvan_ref(res2); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         BDD res = (res1 == res2) ? res1 : sylvan_ite(sylvan_ithvar(va), res2, res1); | 
			
		
	
		
			
				
					|  |  |  |         if (res == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(res1); | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(res2); | 
			
		
	
		
			
				
					|  |  |  |             return sylvan_invalid; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         sylvan_deref(res1); | 
			
		
	
		
			
				
					|  |  |  |         sylvan_deref(res2); | 
			
		
	
		
			
				
					|  |  |  | 		/* TODO: Caching here. */ | 
			
		
	
		
			
				
					|  |  |  |         //cuddCacheInsert2(manager, Cudd_addMinAbstractRepresentative, f, cube, res); | 
			
		
	
		
			
				
					|  |  |  |         return res; | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | TASK_IMPL_3(BDD, mtbdd_maxExistsRepresentative, MTBDD, a, MTBDD, variables, uint32_t, prev_level) { | 
			
		
	
		
			
				
					|  |  |  | 	/* Maybe perform garbage collection */ | 
			
		
	
		
			
				
					|  |  |  |     sylvan_gc_test(); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	if (sylvan_set_isempty(variables)) { | 
			
		
	
		
			
				
					|  |  |  | 		return sylvan_true; | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	/* Cube is guaranteed to be a cube at this point. */ | 
			
		
	
		
			
				
					|  |  |  |     if (mtbdd_isleaf(a)) { | 
			
		
	
		
			
				
					|  |  |  | 		BDD _v = sylvan_set_next(variables); | 
			
		
	
		
			
				
					|  |  |  | 		BDD res = CALL(mtbdd_maxExistsRepresentative, a, _v, prev_level); | 
			
		
	
		
			
				
					|  |  |  | 		if (res == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  | 			return sylvan_invalid; | 
			
		
	
		
			
				
					|  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  | 		sylvan_ref(res); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 		BDD res1 = sylvan_not(sylvan_ite(sylvan_ithvar(bddnode_getvariable(BDD_GETNODE(variables))), sylvan_true, sylvan_not(res))); | 
			
		
	
		
			
				
					|  |  |  | 		if (res1 == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  | 			sylvan_deref(res); | 
			
		
	
		
			
				
					|  |  |  | 			return sylvan_invalid; | 
			
		
	
		
			
				
					|  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  | 		sylvan_deref(res); | 
			
		
	
		
			
				
					|  |  |  | 		return res1; | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  | 	mtbddnode_t na = MTBDD_GETNODE(a); | 
			
		
	
		
			
				
					|  |  |  | 	uint32_t va = mtbddnode_getvariable(na); | 
			
		
	
	
		
			
				
					|  |  | @ -763,16 +880,15 @@ TASK_IMPL_3(BDD, mtbdd_minExistsRepresentative, MTBDD, a, BDD, variables, BDDVAR | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |     /* Abstract a variable that does not appear in a. */ | 
			
		
	
		
			
				
					|  |  |  |     if (va > vv) { | 
			
		
	
		
			
				
					|  |  |  | 		printf("va > vv\n"); | 
			
		
	
		
			
				
					|  |  |  | 		BDD _v = sylvan_set_next(variables); | 
			
		
	
		
			
				
					|  |  |  |         BDD res = CALL(mtbdd_minExistsRepresentative, a, _v, va); | 
			
		
	
		
			
				
					|  |  |  |         BDD res = CALL(mtbdd_maxExistsRepresentative, a, _v, va); | 
			
		
	
		
			
				
					|  |  |  |         if (res == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  |             return sylvan_invalid; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |         // Fill in the missing variables to make representative unique. | 
			
		
	
		
			
				
					|  |  |  |         sylvan_ref(res); | 
			
		
	
		
			
				
					|  |  |  |         BDD res1 = sylvan_ite(sylvan_ithvar(vv), zero, res); | 
			
		
	
		
			
				
					|  |  |  |         BDD res1 = sylvan_ite(sylvan_ithvar(vv), sylvan_false, res); | 
			
		
	
		
			
				
					|  |  |  |         if (res1 == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(res); | 
			
		
	
		
			
				
					|  |  |  |             return sylvan_invalid; | 
			
		
	
	
		
			
				
					|  |  | @ -792,22 +908,21 @@ TASK_IMPL_3(BDD, mtbdd_minExistsRepresentative, MTBDD, a, BDD, variables, BDDVAR | 
			
		
	
		
			
				
					|  |  |  |      | 
			
		
	
		
			
				
					|  |  |  |     /* If the two indices are the same, so are their levels. */ | 
			
		
	
		
			
				
					|  |  |  |     if (va == vv) { | 
			
		
	
		
			
				
					|  |  |  | 		printf("va == vv\n"); | 
			
		
	
		
			
				
					|  |  |  | 		BDD _v = sylvan_set_next(variables); | 
			
		
	
		
			
				
					|  |  |  |         BDD res1 = CALL(mtbdd_minExistsRepresentative, E, _v, va); | 
			
		
	
		
			
				
					|  |  |  |         BDD res1 = CALL(mtbdd_maxExistsRepresentative, E, _v, va); | 
			
		
	
		
			
				
					|  |  |  |         if (res1 == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  |             return sylvan_invalid; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         sylvan_ref(res1); | 
			
		
	
		
			
				
					|  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |         BDD res2 = CALL(mtbdd_minExistsRepresentative, T, _v, va); | 
			
		
	
		
			
				
					|  |  |  |         BDD res2 = CALL(mtbdd_maxExistsRepresentative, T, _v, va); | 
			
		
	
		
			
				
					|  |  |  |         if (res2 == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(res1); | 
			
		
	
		
			
				
					|  |  |  |             return sylvan_invalid; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         sylvan_ref(res2); | 
			
		
	
		
			
				
					|  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |         MTBDD left = mtbdd_abstract_min(E, _v); | 
			
		
	
		
			
				
					|  |  |  |         MTBDD left = mtbdd_abstract_max(E, _v); | 
			
		
	
		
			
				
					|  |  |  |         if (left == mtbdd_invalid) { | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(res1); | 
			
		
	
		
			
				
					|  |  |  | 			sylvan_deref(res2); | 
			
		
	
	
		
			
				
					|  |  | @ -815,7 +930,7 @@ TASK_IMPL_3(BDD, mtbdd_minExistsRepresentative, MTBDD, a, BDD, variables, BDDVAR | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         mtbdd_ref(left); | 
			
		
	
		
			
				
					|  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  |         MTBDD right = mtbdd_abstract_min(T, _v); | 
			
		
	
		
			
				
					|  |  |  |         MTBDD right = mtbdd_abstract_max(T, _v); | 
			
		
	
		
			
				
					|  |  |  |         if (right == mtbdd_invalid) { | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(res1); | 
			
		
	
		
			
				
					|  |  |  | 			sylvan_deref(res2); | 
			
		
	
	
		
			
				
					|  |  | @ -824,7 +939,7 @@ TASK_IMPL_3(BDD, mtbdd_minExistsRepresentative, MTBDD, a, BDD, variables, BDDVAR | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         mtbdd_ref(right); | 
			
		
	
		
			
				
					|  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |         BDD tmp = mtbdd_less_or_equal_as_bdd(left, right); | 
			
		
	
		
			
				
					|  |  |  |         BDD tmp = mtbdd_greater_or_equal_as_bdd(left, right); | 
			
		
	
		
			
				
					|  |  |  |         if (tmp == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(res1); | 
			
		
	
		
			
				
					|  |  |  | 			sylvan_deref(res2); | 
			
		
	
	
		
			
				
					|  |  | @ -837,7 +952,7 @@ TASK_IMPL_3(BDD, mtbdd_minExistsRepresentative, MTBDD, a, BDD, variables, BDDVAR | 
			
		
	
		
			
				
					|  |  |  |         mtbdd_deref(left); | 
			
		
	
		
			
				
					|  |  |  | 		mtbdd_deref(right); | 
			
		
	
		
			
				
					|  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |         BDD res1Inf = sylvan_ite(tmp, res1, zero); | 
			
		
	
		
			
				
					|  |  |  |         BDD res1Inf = sylvan_ite(tmp, res1, sylvan_false); | 
			
		
	
		
			
				
					|  |  |  |         if (res1Inf == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(res1); | 
			
		
	
		
			
				
					|  |  |  | 			sylvan_deref(res2); | 
			
		
	
	
		
			
				
					|  |  | @ -846,30 +961,19 @@ TASK_IMPL_3(BDD, mtbdd_minExistsRepresentative, MTBDD, a, BDD, variables, BDDVAR | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         sylvan_ref(res1Inf); | 
			
		
	
		
			
				
					|  |  |  |         sylvan_deref(res1); | 
			
		
	
		
			
				
					|  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |         BDD tmp2 = sylvan_not(tmp); | 
			
		
	
		
			
				
					|  |  |  |         if (tmp2 == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  | 			sylvan_deref(res2); | 
			
		
	
		
			
				
					|  |  |  | 			mtbdd_deref(left); | 
			
		
	
		
			
				
					|  |  |  | 			mtbdd_deref(right); | 
			
		
	
		
			
				
					|  |  |  | 			sylvan_deref(tmp); | 
			
		
	
		
			
				
					|  |  |  |             return sylvan_invalid; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         sylvan_ref(tmp2); | 
			
		
	
		
			
				
					|  |  |  |         sylvan_deref(tmp); | 
			
		
	
		
			
				
					|  |  |  |          | 
			
		
	
		
			
				
					|  |  |  |         BDD res2Inf = sylvan_ite(tmp2, res2, zero); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         BDD res2Inf = sylvan_ite(tmp, sylvan_false, res2); | 
			
		
	
		
			
				
					|  |  |  |         if (res2Inf == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(res2); | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(res1Inf); | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(tmp2); | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(tmp); | 
			
		
	
		
			
				
					|  |  |  |             return sylvan_invalid; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         sylvan_ref(res2Inf); | 
			
		
	
		
			
				
					|  |  |  |         sylvan_deref(res2); | 
			
		
	
		
			
				
					|  |  |  |         sylvan_deref(tmp2); | 
			
		
	
		
			
				
					|  |  |  |         sylvan_deref(tmp); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         BDD res = (res1Inf == res2Inf) ? sylvan_ite(sylvan_ithvar(va), zero, res1Inf) : sylvan_ite(sylvan_ithvar(va), res2Inf, res1Inf); | 
			
		
	
		
			
				
					|  |  |  |         BDD res = (res1Inf == res2Inf) ? sylvan_ite(sylvan_ithvar(va), sylvan_false, res1Inf) : sylvan_ite(sylvan_ithvar(va), res2Inf, res1Inf); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         if (res == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(res1Inf); | 
			
		
	
	
		
			
				
					|  |  | @ -887,20 +991,19 @@ TASK_IMPL_3(BDD, mtbdd_minExistsRepresentative, MTBDD, a, BDD, variables, BDDVAR | 
			
		
	
		
			
				
					|  |  |  |         return res; | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |     else { /* if (va < vv) */ | 
			
		
	
		
			
				
					|  |  |  | 		printf("va < vv\n"); | 
			
		
	
		
			
				
					|  |  |  | 		BDD res1 = CALL(mtbdd_minExistsRepresentative, E, variables, va); | 
			
		
	
		
			
				
					|  |  |  | 		BDD res1 = CALL(mtbdd_maxExistsRepresentative, E, variables, va); | 
			
		
	
		
			
				
					|  |  |  |         if (res1 == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  | 			return sylvan_invalid; | 
			
		
	
		
			
				
					|  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |         sylvan_ref(res1); | 
			
		
	
		
			
				
					|  |  |  |         BDD res2 = CALL(mtbdd_minExistsRepresentative, T, variables, va); | 
			
		
	
		
			
				
					|  |  |  |         BDD res2 = CALL(mtbdd_maxExistsRepresentative, T, variables, va); | 
			
		
	
		
			
				
					|  |  |  |         if (res2 == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(res1); | 
			
		
	
		
			
				
					|  |  |  |             return sylvan_invalid; | 
			
		
	
		
			
				
					|  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |         sylvan_ref(res2); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |         BDD res = (res1 == res2) ? sylvan_ite(sylvan_ithvar(va), zero, res1) : sylvan_ite(sylvan_ithvar(va), res2, res1); | 
			
		
	
		
			
				
					|  |  |  |         BDD res = (res1 == res2) ? res1 : sylvan_ite(sylvan_ithvar(va), res2, res1); | 
			
		
	
		
			
				
					|  |  |  |         if (res == sylvan_invalid) { | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(res1); | 
			
		
	
		
			
				
					|  |  |  |             sylvan_deref(res2); | 
			
		
	
	
		
			
				
					|  |  | @ -911,11 +1014,5 @@ TASK_IMPL_3(BDD, mtbdd_minExistsRepresentative, MTBDD, a, BDD, variables, BDDVAR | 
			
		
	
		
			
				
					|  |  |  | 		/* TODO: Caching here. */ | 
			
		
	
		
			
				
					|  |  |  |         //cuddCacheInsert2(manager, Cudd_addMinAbstractRepresentative, f, cube, res); | 
			
		
	
		
			
				
					|  |  |  |         return res; | 
			
		
	
		
			
				
					|  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | TASK_IMPL_3(BDD, mtbdd_maxExistsRepresentative, MTBDD, a, MTBDD, variables, uint32_t, prev_level) { | 
			
		
	
		
			
				
					|  |  |  | 	(void)variables; | 
			
		
	
		
			
				
					|  |  |  | 	(void)prev_level; | 
			
		
	
		
			
				
					|  |  |  | 	return a;	 | 
			
		
	
		
			
				
					|  |  |  |     }	 | 
			
		
	
		
			
				
					|  |  |  | } |