From 80b864e42c6067181c232555e1530c235f639259 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 28 Nov 2025 13:29:36 +0000 Subject: [PATCH 1/5] Initial plan From 0538b5c7780c50537a93fed483f2eaa275b4a0e4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 28 Nov 2025 15:15:18 +0000 Subject: [PATCH 2/5] Add comprehensive test cases for cuddAPI.c functions Co-authored-by: doganulus <1174212+doganulus@users.noreply.github.com> --- tests/cuddAPI.test.cpp | 1127 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 1116 insertions(+), 11 deletions(-) diff --git a/tests/cuddAPI.test.cpp b/tests/cuddAPI.test.cpp index d9748324..8f55bc4f 100644 --- a/tests/cuddAPI.test.cpp +++ b/tests/cuddAPI.test.cpp @@ -1,19 +1,1124 @@ #include - -// Include CUDD headers #include "cudd/cudd.h" +#include "cuddInt.h" // For CUDD_CONST_INDEX + #include "util.h" +#include /** - * @brief Test file for cuddAPI.c - * - * This file contains basic tests to ensure the cuddAPI module - * compiles and links correctly with the test suite. + * @brief Comprehensive test file for cuddAPI.c targeting 90% coverage */ -TEST_CASE("cuddAPI - Basic Module Test", "[cuddAPI]") { - // Basic test to verify the module compiles and links - // This is a placeholder test that should be expanded with actual - // functionality tests for the cuddAPI module - REQUIRE(true); +// Test hook function for hook tests +static int testHookFunction(DdManager *dd, const char *str, void *data) { + (void)dd; (void)str; (void)data; + return 1; +} + +// ============================================================================ +// Variable Creation Functions +// ============================================================================ + +TEST_CASE("Cudd_addNewVar - ADD variable creation", "[cuddAPI]") { + DdManager *dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + SECTION("Create new ADD variable") { + DdNode *var = Cudd_addNewVar(dd); + REQUIRE(var != nullptr); + REQUIRE(Cudd_ReadSize(dd) == 1); + } + + SECTION("Create multiple ADD variables") { + for (int i = 0; i < 5; i++) { + DdNode *var = Cudd_addNewVar(dd); + REQUIRE(var != nullptr); + } + REQUIRE(Cudd_ReadSize(dd) == 5); + } + + Cudd_Quit(dd); +} + +TEST_CASE("Cudd_addNewVarAtLevel - ADD variable at level", "[cuddAPI]") { + DdManager *dd = Cudd_Init(3, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + SECTION("Create variable at level >= size") { + DdNode *var = Cudd_addNewVarAtLevel(dd, 10); + REQUIRE(var != nullptr); + } + + SECTION("Create variable at level < size") { + DdNode *var = Cudd_addNewVarAtLevel(dd, 1); + REQUIRE(var != nullptr); + } + + Cudd_Quit(dd); +} + +TEST_CASE("Cudd_bddNewVar - BDD variable creation", "[cuddAPI]") { + DdManager *dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + DdNode *var = Cudd_bddNewVar(dd); + REQUIRE(var != nullptr); + REQUIRE(Cudd_ReadSize(dd) == 1); + + Cudd_Quit(dd); +} + +TEST_CASE("Cudd_bddNewVarAtLevel - BDD variable at level", "[cuddAPI]") { + DdManager *dd = Cudd_Init(3, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + SECTION("Level >= size") { + DdNode *var = Cudd_bddNewVarAtLevel(dd, 10); + REQUIRE(var != nullptr); + } + + SECTION("Level < size") { + DdNode *var = Cudd_bddNewVarAtLevel(dd, 1); + REQUIRE(var != nullptr); + } + + Cudd_Quit(dd); +} + +TEST_CASE("Cudd_bddIsVar - Check if node is variable", "[cuddAPI]") { + DdManager *dd = Cudd_Init(2, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + DdNode *var = Cudd_bddIthVar(dd, 0); + REQUIRE(Cudd_bddIsVar(dd, var) == 1); + + DdNode *one = Cudd_ReadOne(dd); + REQUIRE(Cudd_bddIsVar(dd, one) == 0); + + Cudd_Quit(dd); +} + +TEST_CASE("Cudd_addIthVar - ADD i-th variable", "[cuddAPI]") { + DdManager *dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + DdNode *var = Cudd_addIthVar(dd, 5); + REQUIRE(var != nullptr); + + Cudd_Quit(dd); +} + +TEST_CASE("Cudd_bddIthVar - BDD i-th variable", "[cuddAPI]") { + DdManager *dd = Cudd_Init(5, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + SECTION("Existing variable") { + DdNode *var = Cudd_bddIthVar(dd, 2); + REQUIRE(var != nullptr); + } + + SECTION("New variable") { + DdNode *var = Cudd_bddIthVar(dd, 10); + REQUIRE(var != nullptr); + } + + Cudd_Quit(dd); +} + +TEST_CASE("Cudd_zddIthVar - ZDD i-th variable", "[cuddAPI]") { + DdManager *dd = Cudd_Init(0, 5, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + DdNode *var = Cudd_zddIthVar(dd, 2); + REQUIRE(var != nullptr); + + Cudd_Quit(dd); +} + +TEST_CASE("Cudd_zddVarsFromBddVars - Create ZDD vars from BDD vars", "[cuddAPI]") { + DdManager *dd = Cudd_Init(3, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + SECTION("Multiplicity 1") { + int result = Cudd_zddVarsFromBddVars(dd, 1); + REQUIRE(result == 1); + } + + SECTION("Multiplicity 2") { + int result = Cudd_zddVarsFromBddVars(dd, 2); + REQUIRE(result == 1); + } + + SECTION("Invalid multiplicity") { + int result = Cudd_zddVarsFromBddVars(dd, 0); + REQUIRE(result == 0); + } + + Cudd_Quit(dd); +} + +TEST_CASE("Cudd_ReadMaxIndex - Maximum index", "[cuddAPI]") { + unsigned int maxIdx = Cudd_ReadMaxIndex(); + REQUIRE(maxIdx > 0); +} + +// ============================================================================ +// Constant Functions +// ============================================================================ + +TEST_CASE("Cudd_addConst - ADD constant", "[cuddAPI]") { + DdManager *dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + DdNode *c = Cudd_addConst(dd, 3.14); + REQUIRE(c != nullptr); + REQUIRE(Cudd_V(c) == 3.14); + + Cudd_Quit(dd); +} + +TEST_CASE("Cudd_IsConstant and Cudd_IsNonConstant", "[cuddAPI]") { + DdManager *dd = Cudd_Init(2, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + DdNode *one = Cudd_ReadOne(dd); + REQUIRE(Cudd_IsConstant(one) == 1); + + DdNode *var = Cudd_bddIthVar(dd, 0); + REQUIRE(Cudd_IsConstant(var) == 0); + REQUIRE(Cudd_IsNonConstant(var) == 1); + + Cudd_Quit(dd); +} + +TEST_CASE("Cudd_T, Cudd_E, Cudd_V - Node accessors", "[cuddAPI]") { + DdManager *dd = Cudd_Init(2, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + DdNode *var = Cudd_bddIthVar(dd, 0); + DdNode *t = Cudd_T(var); + DdNode *e = Cudd_E(var); + REQUIRE(t != nullptr); + REQUIRE(e != nullptr); + + DdNode *one = Cudd_ReadOne(dd); + CUDD_VALUE_TYPE val = Cudd_V(one); + REQUIRE(val == 1.0); + + Cudd_Quit(dd); +} + +// ============================================================================ +// Time Management Functions +// ============================================================================ + +TEST_CASE("Time management functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + SECTION("ReadStartTime and SetStartTime") { + unsigned long st = Cudd_ReadStartTime(dd); + Cudd_SetStartTime(dd, st + 100); + REQUIRE(Cudd_ReadStartTime(dd) == st + 100); + } + + SECTION("ResetStartTime") { + Cudd_ResetStartTime(dd); + unsigned long st = Cudd_ReadStartTime(dd); + REQUIRE(st >= 0); + } + + SECTION("ReadElapsedTime") { + unsigned long elapsed = Cudd_ReadElapsedTime(dd); + REQUIRE(elapsed >= 0); + } + + SECTION("Time limit functions") { + unsigned long old = Cudd_SetTimeLimit(dd, 5000); + REQUIRE(Cudd_ReadTimeLimit(dd) == 5000); + REQUIRE(Cudd_TimeLimited(dd) == 1); + + Cudd_IncreaseTimeLimit(dd, 1000); + REQUIRE(Cudd_ReadTimeLimit(dd) == 6000); + + Cudd_UnsetTimeLimit(dd); + REQUIRE(Cudd_TimeLimited(dd) == 0); + + Cudd_IncreaseTimeLimit(dd, 1000); + REQUIRE(Cudd_ReadTimeLimit(dd) == 1000); + } + + SECTION("UpdateTimeLimit") { + Cudd_SetTimeLimit(dd, 10000); + Cudd_UpdateTimeLimit(dd); + REQUIRE(Cudd_ReadTimeLimit(dd) <= 10000); + + Cudd_UnsetTimeLimit(dd); + Cudd_UpdateTimeLimit(dd); + } + + Cudd_Quit(dd); +} + +// ============================================================================ +// Callback Functions +// ============================================================================ + +TEST_CASE("Callback registration functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + SECTION("Termination callback") { + Cudd_RegisterTerminationCallback(dd, nullptr, nullptr); + Cudd_UnregisterTerminationCallback(dd); + } + + SECTION("Out of memory callback") { + DD_OOMFP old = Cudd_RegisterOutOfMemoryCallback(dd, Cudd_OutOfMemSilent); + REQUIRE(old != nullptr); + Cudd_UnregisterOutOfMemoryCallback(dd); + } + + SECTION("Timeout handler") { + Cudd_RegisterTimeoutHandler(dd, nullptr, nullptr); + void *arg; + DD_TOHFP handler = Cudd_ReadTimeoutHandler(dd, &arg); + REQUIRE(handler == nullptr); + + handler = Cudd_ReadTimeoutHandler(dd, nullptr); + } + + Cudd_Quit(dd); +} + +// ============================================================================ +// Reordering Functions +// ============================================================================ + +TEST_CASE("Reordering control functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(5, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + SECTION("AutodynEnable/Disable") { + Cudd_AutodynEnable(dd, CUDD_REORDER_SIFT); + Cudd_ReorderingType method; + int status = Cudd_ReorderingStatus(dd, &method); + REQUIRE(status == 1); + REQUIRE(method == CUDD_REORDER_SIFT); + + Cudd_AutodynEnable(dd, CUDD_REORDER_SAME); + + Cudd_AutodynDisable(dd); + status = Cudd_ReorderingStatus(dd, &method); + REQUIRE(status == 0); + + status = Cudd_ReorderingStatus(dd, nullptr); + } + + SECTION("ZDD AutodynEnable/Disable") { + Cudd_AutodynEnableZdd(dd, CUDD_REORDER_SIFT); + Cudd_ReorderingType method; + int status = Cudd_ReorderingStatusZdd(dd, &method); + REQUIRE(status == 1); + + Cudd_AutodynEnableZdd(dd, CUDD_REORDER_SAME); + + Cudd_AutodynDisableZdd(dd); + status = Cudd_ReorderingStatusZdd(dd, &method); + REQUIRE(status == 0); + } + + SECTION("Realignment functions") { + REQUIRE(Cudd_zddRealignmentEnabled(dd) == 0); + Cudd_zddRealignEnable(dd); + REQUIRE(Cudd_zddRealignmentEnabled(dd) == 1); + Cudd_zddRealignDisable(dd); + REQUIRE(Cudd_zddRealignmentEnabled(dd) == 0); + + REQUIRE(Cudd_bddRealignmentEnabled(dd) == 0); + Cudd_bddRealignEnable(dd); + REQUIRE(Cudd_bddRealignmentEnabled(dd) == 1); + Cudd_bddRealignDisable(dd); + REQUIRE(Cudd_bddRealignmentEnabled(dd) == 0); + } + + Cudd_Quit(dd); +} + +// ============================================================================ +// Read Constant Functions +// ============================================================================ + +TEST_CASE("Read constant functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(0, 3, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + REQUIRE(Cudd_ReadOne(dd) != nullptr); + REQUIRE(Cudd_ReadZero(dd) != nullptr); + REQUIRE(Cudd_ReadLogicZero(dd) != nullptr); + REQUIRE(Cudd_ReadPlusInfinity(dd) != nullptr); + REQUIRE(Cudd_ReadMinusInfinity(dd) != nullptr); + REQUIRE(Cudd_ReadBackground(dd) != nullptr); + + SECTION("ReadZddOne") { + DdNode *zddOne = Cudd_ReadZddOne(dd, 0); + REQUIRE(zddOne != nullptr); + + zddOne = Cudd_ReadZddOne(dd, -1); + REQUIRE(zddOne == nullptr); + + zddOne = Cudd_ReadZddOne(dd, 10); + REQUIRE(zddOne != nullptr); + } + + SECTION("SetBackground") { + DdNode *zero = Cudd_ReadZero(dd); + Cudd_SetBackground(dd, zero); + REQUIRE(Cudd_ReadBackground(dd) == zero); + } + + Cudd_Quit(dd); +} + +// ============================================================================ +// Cache Functions +// ============================================================================ + +TEST_CASE("Cache functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(5, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + REQUIRE(Cudd_ReadCacheSlots(dd) > 0); + REQUIRE(Cudd_ReadCacheUsedSlots(dd) >= 0.0); + REQUIRE(Cudd_ReadCacheLookUps(dd) >= 0.0); + REQUIRE(Cudd_ReadCacheHits(dd) >= 0.0); + + unsigned int minHit = Cudd_ReadMinHit(dd); + Cudd_SetMinHit(dd, 30); + REQUIRE(Cudd_ReadMinHit(dd) == 30); + + unsigned int maxCache = Cudd_ReadMaxCache(dd); + REQUIRE(maxCache > 0); + + unsigned int maxCacheHard = Cudd_ReadMaxCacheHard(dd); + Cudd_SetMaxCacheHard(dd, 10000); + REQUIRE(Cudd_ReadMaxCacheHard(dd) == 10000); + Cudd_SetMaxCacheHard(dd, 0); + + Cudd_Quit(dd); +} + +// ============================================================================ +// Manager Info Functions +// ============================================================================ + +TEST_CASE("Manager info read functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(5, 3, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + REQUIRE(Cudd_ReadSize(dd) == 5); + REQUIRE(Cudd_ReadZddSize(dd) == 3); + REQUIRE(Cudd_ReadSlots(dd) > 0); + REQUIRE(Cudd_ReadUsedSlots(dd) >= 0.0); + REQUIRE(Cudd_ExpectedUsedSlots(dd) >= 0.0); + REQUIRE(Cudd_ReadKeys(dd) > 0); + REQUIRE(Cudd_ReadDead(dd) >= 0); + REQUIRE(Cudd_ReadMinDead(dd) >= 0); + REQUIRE(Cudd_ReadReorderings(dd) >= 0); + REQUIRE(Cudd_ReadMaxReorderings(dd) > 0); + REQUIRE(Cudd_ReadReorderingTime(dd) >= 0); + REQUIRE(Cudd_ReadGarbageCollections(dd) >= 0); + REQUIRE(Cudd_ReadGarbageCollectionTime(dd) >= 0); + REQUIRE(Cudd_ReadRecursiveCalls(dd) != 0); + REQUIRE(Cudd_ReadNodesFreed(dd) != 0); + REQUIRE(Cudd_ReadNodesDropped(dd) != 0); + REQUIRE(Cudd_ReadUniqueLookUps(dd) != 0); + REQUIRE(Cudd_ReadUniqueLinks(dd) != 0); + REQUIRE(Cudd_ReadMemoryInUse(dd) > 0); + REQUIRE(Cudd_ReadPeakNodeCount(dd) > 0); + REQUIRE(Cudd_ReadPeakLiveNodeCount(dd) > 0); + REQUIRE(Cudd_ReadNodeCount(dd) >= 0); + REQUIRE(Cudd_zddReadNodeCount(dd) >= 0); + REQUIRE(Cudd_ReadSwapSteps(dd) != 0); + + Cudd_SetMaxReorderings(dd, 100); + REQUIRE(Cudd_ReadMaxReorderings(dd) == 100); + + Cudd_Quit(dd); +} + +// ============================================================================ +// Sift Parameters +// ============================================================================ + +TEST_CASE("Sift parameter functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(5, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + int smv = Cudd_ReadSiftMaxVar(dd); + Cudd_SetSiftMaxVar(dd, 100); + REQUIRE(Cudd_ReadSiftMaxVar(dd) == 100); + + int sms = Cudd_ReadSiftMaxSwap(dd); + Cudd_SetSiftMaxSwap(dd, 200); + REQUIRE(Cudd_ReadSiftMaxSwap(dd) == 200); + + double mg = Cudd_ReadMaxGrowth(dd); + Cudd_SetMaxGrowth(dd, 1.5); + REQUIRE(Cudd_ReadMaxGrowth(dd) == 1.5); + + double mga = Cudd_ReadMaxGrowthAlternate(dd); + Cudd_SetMaxGrowthAlternate(dd, 1.2); + REQUIRE(Cudd_ReadMaxGrowthAlternate(dd) == 1.2); + + int cycle = Cudd_ReadReorderingCycle(dd); + Cudd_SetReorderingCycle(dd, 5); + REQUIRE(Cudd_ReadReorderingCycle(dd) == 5); + + Cudd_Quit(dd); +} + +// ============================================================================ +// Loose Up To Functions +// ============================================================================ + +TEST_CASE("LooseUpTo functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + unsigned int lut = Cudd_ReadLooseUpTo(dd); + Cudd_SetLooseUpTo(dd, 50000); + REQUIRE(Cudd_ReadLooseUpTo(dd) == 50000); + Cudd_SetLooseUpTo(dd, 0); + + Cudd_Quit(dd); +} + +// ============================================================================ +// Tree Functions +// ============================================================================ + + +// ============================================================================ +// Permutation Functions +// ============================================================================ + +TEST_CASE("Permutation functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(5, 3, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + SECTION("ReadPerm") { + int perm = Cudd_ReadPerm(dd, 0); + REQUIRE(perm >= 0); + + perm = Cudd_ReadPerm(dd, CUDD_CONST_INDEX); + REQUIRE(perm == CUDD_CONST_INDEX); + + perm = Cudd_ReadPerm(dd, -1); + REQUIRE(perm == -1); + + perm = Cudd_ReadPerm(dd, 100); + REQUIRE(perm == -1); + } + + SECTION("ReadPermZdd") { + int perm = Cudd_ReadPermZdd(dd, 0); + REQUIRE(perm >= 0); + + perm = Cudd_ReadPermZdd(dd, CUDD_CONST_INDEX); + REQUIRE(perm == CUDD_CONST_INDEX); + + perm = Cudd_ReadPermZdd(dd, -1); + REQUIRE(perm == -1); + + perm = Cudd_ReadPermZdd(dd, 100); + REQUIRE(perm == -1); + } + + SECTION("ReadInvPerm") { + int inv = Cudd_ReadInvPerm(dd, 0); + REQUIRE(inv >= 0); + + inv = Cudd_ReadInvPerm(dd, CUDD_CONST_INDEX); + REQUIRE(inv == CUDD_CONST_INDEX); + + inv = Cudd_ReadInvPerm(dd, -1); + REQUIRE(inv == -1); + + inv = Cudd_ReadInvPerm(dd, 100); + REQUIRE(inv == -1); + } + + SECTION("ReadInvPermZdd") { + int inv = Cudd_ReadInvPermZdd(dd, 0); + REQUIRE(inv >= 0); + + inv = Cudd_ReadInvPermZdd(dd, CUDD_CONST_INDEX); + REQUIRE(inv == CUDD_CONST_INDEX); + + inv = Cudd_ReadInvPermZdd(dd, -1); + REQUIRE(inv == -1); + + inv = Cudd_ReadInvPermZdd(dd, 100); + REQUIRE(inv == -1); + } + + SECTION("NodeReadIndex") { + DdNode *var = Cudd_bddIthVar(dd, 2); + unsigned int idx = Cudd_NodeReadIndex(var); + REQUIRE(idx == 2); + } + + SECTION("ReadVars") { + DdNode *var = Cudd_ReadVars(dd, 0); + REQUIRE(var != nullptr); + + var = Cudd_ReadVars(dd, -1); + REQUIRE(var == nullptr); + + var = Cudd_ReadVars(dd, 100); + REQUIRE(var == nullptr); + } + + Cudd_Quit(dd); +} + +// ============================================================================ +// Epsilon Functions +// ============================================================================ + +TEST_CASE("Epsilon functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + CUDD_VALUE_TYPE ep = Cudd_ReadEpsilon(dd); + Cudd_SetEpsilon(dd, 0.001); + REQUIRE(Cudd_ReadEpsilon(dd) == 0.001); + + Cudd_Quit(dd); +} + +// ============================================================================ +// Groupcheck Functions +// ============================================================================ + +TEST_CASE("Groupcheck functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + Cudd_AggregationType gc = Cudd_ReadGroupcheck(dd); + Cudd_SetGroupcheck(dd, CUDD_GROUP_CHECK5); + REQUIRE(Cudd_ReadGroupcheck(dd) == CUDD_GROUP_CHECK5); + + Cudd_Quit(dd); +} + +// ============================================================================ +// Garbage Collection Functions +// ============================================================================ + +TEST_CASE("Garbage collection functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + REQUIRE(Cudd_GarbageCollectionEnabled(dd) == 1); + Cudd_DisableGarbageCollection(dd); + REQUIRE(Cudd_GarbageCollectionEnabled(dd) == 0); + Cudd_EnableGarbageCollection(dd); + REQUIRE(Cudd_GarbageCollectionEnabled(dd) == 1); + + Cudd_Quit(dd); +} + +// ============================================================================ +// Dead Counting Functions +// ============================================================================ + +TEST_CASE("Dead counting functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + Cudd_TurnOnCountDead(dd); + REQUIRE(Cudd_DeadAreCounted(dd) == 1); + Cudd_TurnOffCountDead(dd); + REQUIRE(Cudd_DeadAreCounted(dd) == 0); + + Cudd_Quit(dd); +} + +// ============================================================================ +// Recomb Functions +// ============================================================================ + +TEST_CASE("Recomb functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + int recomb = Cudd_ReadRecomb(dd); + Cudd_SetRecomb(dd, 5); + REQUIRE(Cudd_ReadRecomb(dd) == 5); + + int symm = Cudd_ReadSymmviolation(dd); + Cudd_SetSymmviolation(dd, 10); + REQUIRE(Cudd_ReadSymmviolation(dd) == 10); + + int arc = Cudd_ReadArcviolation(dd); + Cudd_SetArcviolation(dd, 15); + REQUIRE(Cudd_ReadArcviolation(dd) == 15); + + Cudd_Quit(dd); +} + +// ============================================================================ +// Population Size Functions +// ============================================================================ + +TEST_CASE("Population size functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + int pop = Cudd_ReadPopulationSize(dd); + Cudd_SetPopulationSize(dd, 50); + REQUIRE(Cudd_ReadPopulationSize(dd) == 50); + + int xov = Cudd_ReadNumberXovers(dd); + Cudd_SetNumberXovers(dd, 30); + REQUIRE(Cudd_ReadNumberXovers(dd) == 30); + + Cudd_Quit(dd); +} + +// ============================================================================ +// Order Randomization Functions +// ============================================================================ + +TEST_CASE("Order randomization functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + unsigned int rand = Cudd_ReadOrderRandomization(dd); + Cudd_SetOrderRandomization(dd, 5); + REQUIRE(Cudd_ReadOrderRandomization(dd) == 5); + + Cudd_Quit(dd); +} + +// ============================================================================ +// Hook Functions +// ============================================================================ + +TEST_CASE("Hook functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + SECTION("Add and remove hooks") { + int result = Cudd_AddHook(dd, testHookFunction, CUDD_PRE_GC_HOOK); + REQUIRE(result == 1); + + result = Cudd_AddHook(dd, testHookFunction, CUDD_PRE_GC_HOOK); + REQUIRE(result == 2); + + REQUIRE(Cudd_IsInHook(dd, testHookFunction, CUDD_PRE_GC_HOOK) == 1); + + result = Cudd_RemoveHook(dd, testHookFunction, CUDD_PRE_GC_HOOK); + REQUIRE(result == 1); + + REQUIRE(Cudd_IsInHook(dd, testHookFunction, CUDD_PRE_GC_HOOK) == 0); + + result = Cudd_RemoveHook(dd, testHookFunction, CUDD_PRE_GC_HOOK); + REQUIRE(result == 0); + } + + SECTION("All hook types") { + Cudd_AddHook(dd, testHookFunction, CUDD_POST_GC_HOOK); + REQUIRE(Cudd_IsInHook(dd, testHookFunction, CUDD_POST_GC_HOOK) == 1); + Cudd_RemoveHook(dd, testHookFunction, CUDD_POST_GC_HOOK); + + Cudd_AddHook(dd, testHookFunction, CUDD_PRE_REORDERING_HOOK); + REQUIRE(Cudd_IsInHook(dd, testHookFunction, CUDD_PRE_REORDERING_HOOK) == 1); + Cudd_RemoveHook(dd, testHookFunction, CUDD_PRE_REORDERING_HOOK); + + Cudd_AddHook(dd, testHookFunction, CUDD_POST_REORDERING_HOOK); + REQUIRE(Cudd_IsInHook(dd, testHookFunction, CUDD_POST_REORDERING_HOOK) == 1); + Cudd_RemoveHook(dd, testHookFunction, CUDD_POST_REORDERING_HOOK); + } + + SECTION("Invalid hook type") { + int result = Cudd_AddHook(dd, testHookFunction, (Cudd_HookType)99); + REQUIRE(result == 0); + + result = Cudd_RemoveHook(dd, testHookFunction, (Cudd_HookType)99); + REQUIRE(result == 0); + + result = Cudd_IsInHook(dd, testHookFunction, (Cudd_HookType)99); + REQUIRE(result == 0); + } + + Cudd_Quit(dd); +} + +// ============================================================================ +// Reordering Reporting Functions +// ============================================================================ + +TEST_CASE("Reordering reporting functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(5, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + SECTION("Enable/Disable reordering reporting") { + int result = Cudd_EnableReorderingReporting(dd); + REQUIRE(result == 1); + REQUIRE(Cudd_ReorderingReporting(dd) == 1); + + result = Cudd_DisableReorderingReporting(dd); + REQUIRE(result == 1); + REQUIRE(Cudd_ReorderingReporting(dd) == 0); + } + + SECTION("Enable/Disable ordering monitoring") { + int result = Cudd_EnableOrderingMonitoring(dd); + REQUIRE(result == 1); + REQUIRE(Cudd_OrderingMonitoring(dd) == 1); + + result = Cudd_DisableOrderingMonitoring(dd); + REQUIRE(result == 1); + REQUIRE(Cudd_OrderingMonitoring(dd) == 0); + } + + Cudd_Quit(dd); +} + +// ============================================================================ +// Application Hook Functions +// ============================================================================ + +TEST_CASE("Application hook functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + int data = 42; + Cudd_SetApplicationHook(dd, &data); + void *hook = Cudd_ReadApplicationHook(dd); + REQUIRE(hook == &data); + + Cudd_Quit(dd); +} + +// ============================================================================ +// Error Code Functions +// ============================================================================ + +TEST_CASE("Error code functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + Cudd_ErrorType err = Cudd_ReadErrorCode(dd); + REQUIRE(err == CUDD_NO_ERROR); + + Cudd_ClearErrorCode(dd); + err = Cudd_ReadErrorCode(dd); + REQUIRE(err == CUDD_NO_ERROR); + + Cudd_Quit(dd); +} + +// ============================================================================ +// Out of Memory Handler +// ============================================================================ + +TEST_CASE("Out of memory handler", "[cuddAPI]") { + DD_OOMFP old = Cudd_InstallOutOfMemoryHandler(Cudd_OutOfMemSilent); + REQUIRE(old != nullptr); + Cudd_InstallOutOfMemoryHandler(old); +} + +// ============================================================================ +// Stdio Functions +// ============================================================================ + +TEST_CASE("Stdio functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + FILE *out = Cudd_ReadStdout(dd); + REQUIRE(out != nullptr); + Cudd_SetStdout(dd, stdout); + REQUIRE(Cudd_ReadStdout(dd) == stdout); + + FILE *err = Cudd_ReadStderr(dd); + REQUIRE(err != nullptr); + Cudd_SetStderr(dd, stderr); + REQUIRE(Cudd_ReadStderr(dd) == stderr); + + Cudd_Quit(dd); +} + +// ============================================================================ +// Next Reordering Functions +// ============================================================================ + +TEST_CASE("Next reordering functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + unsigned int next = Cudd_ReadNextReordering(dd); + Cudd_SetNextReordering(dd, 10000); + REQUIRE(Cudd_ReadNextReordering(dd) == 10000); + + Cudd_Quit(dd); +} + +// ============================================================================ +// Max Live and Max Memory Functions +// ============================================================================ + +TEST_CASE("Max live and max memory functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(0, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + unsigned int maxLive = Cudd_ReadMaxLive(dd); + Cudd_SetMaxLive(dd, 100000); + REQUIRE(Cudd_ReadMaxLive(dd) == 100000); + + size_t maxMem = Cudd_ReadMaxMemory(dd); + size_t oldMem = Cudd_SetMaxMemory(dd, 1024*1024*100); + REQUIRE(Cudd_ReadMaxMemory(dd) == 1024*1024*100); + + Cudd_Quit(dd); +} + +// ============================================================================ +// Variable Binding Functions +// ============================================================================ + +TEST_CASE("Variable binding functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(5, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + SECTION("Bind and unbind") { + int result = Cudd_bddBindVar(dd, 0); + REQUIRE(result == 1); + REQUIRE(Cudd_bddVarIsBound(dd, 0) == 1); + + result = Cudd_bddUnbindVar(dd, 0); + REQUIRE(result == 1); + REQUIRE(Cudd_bddVarIsBound(dd, 0) == 0); + } + + SECTION("Invalid index") { + int result = Cudd_bddBindVar(dd, 100); + REQUIRE(result == 0); + + result = Cudd_bddUnbindVar(dd, 100); + REQUIRE(result == 0); + + result = Cudd_bddVarIsBound(dd, 100); + REQUIRE(result == 0); + + result = Cudd_bddBindVar(dd, -1); + REQUIRE(result == 0); + } + + Cudd_Quit(dd); +} + +// ============================================================================ +// Variable Type Functions +// ============================================================================ + +TEST_CASE("Variable type functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(5, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + SECTION("Set and check PI var") { + int result = Cudd_bddSetPiVar(dd, 0); + REQUIRE(result == 1); + REQUIRE(Cudd_bddIsPiVar(dd, 0) == 1); + REQUIRE(Cudd_bddIsPsVar(dd, 0) == 0); + REQUIRE(Cudd_bddIsNsVar(dd, 0) == 0); + } + + SECTION("Set and check PS var") { + int result = Cudd_bddSetPsVar(dd, 1); + REQUIRE(result == 1); + REQUIRE(Cudd_bddIsPsVar(dd, 1) == 1); + } + + SECTION("Set and check NS var") { + int result = Cudd_bddSetNsVar(dd, 2); + REQUIRE(result == 1); + REQUIRE(Cudd_bddIsNsVar(dd, 2) == 1); + } + + SECTION("Invalid index") { + REQUIRE(Cudd_bddSetPiVar(dd, 100) == 0); + REQUIRE(Cudd_bddSetPsVar(dd, 100) == 0); + REQUIRE(Cudd_bddSetNsVar(dd, 100) == 0); + REQUIRE(Cudd_bddIsPiVar(dd, 100) == -1); + REQUIRE(Cudd_bddIsPsVar(dd, 100) == -1); + REQUIRE(Cudd_bddIsNsVar(dd, 100) == -1); + } + + Cudd_Quit(dd); +} + +// ============================================================================ +// Pair Index Functions +// ============================================================================ + +TEST_CASE("Pair index functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(5, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + int result = Cudd_bddSetPairIndex(dd, 0, 1); + REQUIRE(result == 1); + REQUIRE(Cudd_bddReadPairIndex(dd, 0) == 1); + + result = Cudd_bddSetPairIndex(dd, 100, 1); + REQUIRE(result == 0); + + int idx = Cudd_bddReadPairIndex(dd, 100); + REQUIRE(idx == -1); + + Cudd_Quit(dd); +} + +// ============================================================================ +// Variable Grouping Functions +// ============================================================================ + +TEST_CASE("Variable grouping functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(5, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + SECTION("Set var to be grouped") { + int result = Cudd_bddSetVarToBeGrouped(dd, 0); + REQUIRE(result == 1); + REQUIRE(Cudd_bddIsVarToBeGrouped(dd, 0) != 0); + + result = Cudd_bddResetVarToBeGrouped(dd, 0); + REQUIRE(result == 1); + } + + SECTION("Set var hard group") { + int result = Cudd_bddSetVarHardGroup(dd, 1); + REQUIRE(result == 1); + REQUIRE(Cudd_bddIsVarHardGroup(dd, 1) == 1); + } + + SECTION("Set var to be ungrouped") { + int result = Cudd_bddSetVarToBeUngrouped(dd, 2); + REQUIRE(result == 1); + REQUIRE(Cudd_bddIsVarToBeUngrouped(dd, 2) == 1); + } + + SECTION("Invalid index") { + REQUIRE(Cudd_bddSetVarToBeGrouped(dd, 100) == 0); + REQUIRE(Cudd_bddSetVarHardGroup(dd, 100) == 0); + REQUIRE(Cudd_bddResetVarToBeGrouped(dd, 100) == 0); + REQUIRE(Cudd_bddSetVarToBeUngrouped(dd, 100) == 0); + REQUIRE(Cudd_bddIsVarToBeGrouped(dd, 100) == -1); + REQUIRE(Cudd_bddIsVarToBeUngrouped(dd, 100) == -1); + REQUIRE(Cudd_bddIsVarHardGroup(dd, 100) == -1); + } + + Cudd_Quit(dd); +} + +// ============================================================================ +// PrintInfo Function +// ============================================================================ + +TEST_CASE("PrintInfo function", "[cuddAPI]") { + DdManager *dd = Cudd_Init(5, 3, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + FILE *fp = fopen("/dev/null", "w"); + REQUIRE(fp != nullptr); + + int result = Cudd_PrintInfo(dd, fp); + REQUIRE(result == 1); + + fclose(fp); + Cudd_Quit(dd); +} + +// ============================================================================ +// StdPreReordHook and StdPostReordHook Functions +// ============================================================================ + +TEST_CASE("Standard reorder hook functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(5, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + FILE *fp = fopen("/dev/null", "w"); + REQUIRE(fp != nullptr); + Cudd_SetStdout(dd, fp); + + int result = Cudd_StdPreReordHook(dd, "BDD", (void*)(uintptr_t)CUDD_REORDER_SIFT); + REQUIRE(result == 1); + + result = Cudd_StdPreReordHook(dd, "ZDD", (void*)(uintptr_t)CUDD_REORDER_SIFT_CONVERGE); + REQUIRE(result == 1); + + result = Cudd_StdPreReordHook(dd, "BDD", (void*)(uintptr_t)CUDD_REORDER_RANDOM); + REQUIRE(result == 1); + + result = Cudd_StdPreReordHook(dd, "BDD", (void*)(uintptr_t)CUDD_REORDER_SYMM_SIFT); + REQUIRE(result == 1); + + result = Cudd_StdPreReordHook(dd, "BDD", (void*)(uintptr_t)CUDD_REORDER_LAZY_SIFT); + REQUIRE(result == 1); + + result = Cudd_StdPreReordHook(dd, "BDD", (void*)(uintptr_t)CUDD_REORDER_GROUP_SIFT); + REQUIRE(result == 1); + + result = Cudd_StdPreReordHook(dd, "BDD", (void*)(uintptr_t)CUDD_REORDER_WINDOW2); + REQUIRE(result == 1); + + result = Cudd_StdPreReordHook(dd, "BDD", (void*)(uintptr_t)CUDD_REORDER_ANNEALING); + REQUIRE(result == 1); + + result = Cudd_StdPreReordHook(dd, "BDD", (void*)(uintptr_t)CUDD_REORDER_GENETIC); + REQUIRE(result == 1); + + result = Cudd_StdPreReordHook(dd, "BDD", (void*)(uintptr_t)CUDD_REORDER_LINEAR); + REQUIRE(result == 1); + + result = Cudd_StdPreReordHook(dd, "BDD", (void*)(uintptr_t)CUDD_REORDER_EXACT); + REQUIRE(result == 1); + + unsigned long startTime = util_cpu_time(); + result = Cudd_StdPostReordHook(dd, "BDD", (void*)(uintptr_t)startTime); + REQUIRE(result == 1); + + result = Cudd_StdPostReordHook(dd, "ZDD", (void*)(uintptr_t)startTime); + REQUIRE(result == 1); + + fclose(fp); + Cudd_SetStdout(dd, stdout); + Cudd_Quit(dd); +} + +// ============================================================================ +// PrintGroupedOrder Function +// ============================================================================ + +TEST_CASE("PrintGroupedOrder function", "[cuddAPI]") { + DdManager *dd = Cudd_Init(5, 3, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + FILE *fp = fopen("/dev/null", "w"); + REQUIRE(fp != nullptr); + Cudd_SetStdout(dd, fp); + + int result = Cudd_PrintGroupedOrder(dd, "BDD", nullptr); + REQUIRE(result == 1); + + result = Cudd_PrintGroupedOrder(dd, "ZDD", nullptr); + REQUIRE(result == 1); + + fclose(fp); + Cudd_SetStdout(dd, stdout); + Cudd_Quit(dd); } From 1815cc0476e04fd40d1c07f1c6929cd44b8698b0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 28 Nov 2025 15:28:28 +0000 Subject: [PATCH 3/5] Address code review feedback: use tmpfile(), fix unsigned comparisons, remove internal header Co-authored-by: doganulus <1174212+doganulus@users.noreply.github.com> --- tests/cuddAPI.test.cpp | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/tests/cuddAPI.test.cpp b/tests/cuddAPI.test.cpp index 8f55bc4f..fe14b472 100644 --- a/tests/cuddAPI.test.cpp +++ b/tests/cuddAPI.test.cpp @@ -1,14 +1,17 @@ #include #include "cudd/cudd.h" -#include "cuddInt.h" // For CUDD_CONST_INDEX - #include "util.h" #include +#include /** * @brief Comprehensive test file for cuddAPI.c targeting 90% coverage */ +// Define constant index for testing (matches CUDD_MAXINDEX) +// This represents a constant/terminal node index +static const int TEST_CONST_INDEX = ((unsigned int) ~0 >> 1); + // Test hook function for hook tests static int testHookFunction(DdManager *dd, const char *str, void *data) { (void)dd; (void)str; (void)data; @@ -225,12 +228,14 @@ TEST_CASE("Time management functions", "[cuddAPI]") { SECTION("ResetStartTime") { Cudd_ResetStartTime(dd); unsigned long st = Cudd_ReadStartTime(dd); - REQUIRE(st >= 0); + // Just verify we can read the value (unsigned is always >= 0) + (void)st; } SECTION("ReadElapsedTime") { unsigned long elapsed = Cudd_ReadElapsedTime(dd); - REQUIRE(elapsed >= 0); + // Just verify we can read the value (unsigned is always >= 0) + (void)elapsed; } SECTION("Time limit functions") { @@ -511,8 +516,8 @@ TEST_CASE("Permutation functions", "[cuddAPI]") { int perm = Cudd_ReadPerm(dd, 0); REQUIRE(perm >= 0); - perm = Cudd_ReadPerm(dd, CUDD_CONST_INDEX); - REQUIRE(perm == CUDD_CONST_INDEX); + perm = Cudd_ReadPerm(dd, TEST_CONST_INDEX); + REQUIRE(perm == TEST_CONST_INDEX); perm = Cudd_ReadPerm(dd, -1); REQUIRE(perm == -1); @@ -525,8 +530,8 @@ TEST_CASE("Permutation functions", "[cuddAPI]") { int perm = Cudd_ReadPermZdd(dd, 0); REQUIRE(perm >= 0); - perm = Cudd_ReadPermZdd(dd, CUDD_CONST_INDEX); - REQUIRE(perm == CUDD_CONST_INDEX); + perm = Cudd_ReadPermZdd(dd, TEST_CONST_INDEX); + REQUIRE(perm == TEST_CONST_INDEX); perm = Cudd_ReadPermZdd(dd, -1); REQUIRE(perm == -1); @@ -539,8 +544,8 @@ TEST_CASE("Permutation functions", "[cuddAPI]") { int inv = Cudd_ReadInvPerm(dd, 0); REQUIRE(inv >= 0); - inv = Cudd_ReadInvPerm(dd, CUDD_CONST_INDEX); - REQUIRE(inv == CUDD_CONST_INDEX); + inv = Cudd_ReadInvPerm(dd, TEST_CONST_INDEX); + REQUIRE(inv == TEST_CONST_INDEX); inv = Cudd_ReadInvPerm(dd, -1); REQUIRE(inv == -1); @@ -553,8 +558,8 @@ TEST_CASE("Permutation functions", "[cuddAPI]") { int inv = Cudd_ReadInvPermZdd(dd, 0); REQUIRE(inv >= 0); - inv = Cudd_ReadInvPermZdd(dd, CUDD_CONST_INDEX); - REQUIRE(inv == CUDD_CONST_INDEX); + inv = Cudd_ReadInvPermZdd(dd, TEST_CONST_INDEX); + REQUIRE(inv == TEST_CONST_INDEX); inv = Cudd_ReadInvPermZdd(dd, -1); REQUIRE(inv == -1); @@ -1033,7 +1038,7 @@ TEST_CASE("PrintInfo function", "[cuddAPI]") { DdManager *dd = Cudd_Init(5, 3, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); REQUIRE(dd != nullptr); - FILE *fp = fopen("/dev/null", "w"); + FILE *fp = tmpfile(); REQUIRE(fp != nullptr); int result = Cudd_PrintInfo(dd, fp); @@ -1051,7 +1056,7 @@ TEST_CASE("Standard reorder hook functions", "[cuddAPI]") { DdManager *dd = Cudd_Init(5, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); REQUIRE(dd != nullptr); - FILE *fp = fopen("/dev/null", "w"); + FILE *fp = tmpfile(); REQUIRE(fp != nullptr); Cudd_SetStdout(dd, fp); @@ -1108,7 +1113,7 @@ TEST_CASE("PrintGroupedOrder function", "[cuddAPI]") { DdManager *dd = Cudd_Init(5, 3, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); REQUIRE(dd != nullptr); - FILE *fp = fopen("/dev/null", "w"); + FILE *fp = tmpfile(); REQUIRE(fp != nullptr); Cudd_SetStdout(dd, fp); From 4291f6eaa5225e1a1a4e5daf1549731ecdc3be30 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 28 Nov 2025 16:26:57 +0000 Subject: [PATCH 4/5] Add extended tests for cuddAPI.c to improve coverage Co-authored-by: doganulus <1174212+doganulus@users.noreply.github.com> --- tests/cuddAPI.test.cpp | 434 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 434 insertions(+) diff --git a/tests/cuddAPI.test.cpp b/tests/cuddAPI.test.cpp index fe14b472..a74d1d99 100644 --- a/tests/cuddAPI.test.cpp +++ b/tests/cuddAPI.test.cpp @@ -1,4 +1,6 @@ #include +// Include CUDD headers - mtr.h must come before cudd.h for tree functions +#include "mtr.h" #include "cudd/cudd.h" #include "util.h" #include @@ -1127,3 +1129,435 @@ TEST_CASE("PrintGroupedOrder function", "[cuddAPI]") { Cudd_SetStdout(dd, stdout); Cudd_Quit(dd); } + +// ============================================================================ +// Extended zddVarsFromBddVars Tests for Better Coverage +// ============================================================================ + +TEST_CASE("Cudd_zddVarsFromBddVars - Extended coverage", "[cuddAPI]") { + SECTION("With existing ZDD variables (non-allnew path)") { + DdManager *dd = Cudd_Init(3, 3, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + // ZDD vars already exist, so this triggers the non-allnew path + int result = Cudd_zddVarsFromBddVars(dd, 1); + REQUIRE(result == 1); + + Cudd_Quit(dd); + } + + SECTION("With multiplicity > 1 and existing ZDD vars") { + DdManager *dd = Cudd_Init(2, 2, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + // Test multiplicity with existing ZDD variables + int result = Cudd_zddVarsFromBddVars(dd, 2); + REQUIRE(result == 1); + + Cudd_Quit(dd); + } + + SECTION("With BDD tree existing") { + DdManager *dd = Cudd_Init(4, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + // Create a group tree for BDD variables + MtrNode *tree = Cudd_MakeTreeNode(dd, 0, 4, MTR_DEFAULT); + REQUIRE(tree != nullptr); + + // Now create ZDD vars from BDD vars with multiplicity 2 + int result = Cudd_zddVarsFromBddVars(dd, 2); + REQUIRE(result == 1); + + Cudd_Quit(dd); + } + + SECTION("Large multiplicity") { + DdManager *dd = Cudd_Init(2, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + int result = Cudd_zddVarsFromBddVars(dd, 3); + REQUIRE(result == 1); + + Cudd_Quit(dd); + } +} + +// ============================================================================ +// Tree Functions Extended Tests +// ============================================================================ + +TEST_CASE("Tree functions extended coverage", "[cuddAPI]") { + SECTION("Set tree with actual tree node") { + DdManager *dd = Cudd_Init(4, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + // Create a tree node + MtrNode *tree = Cudd_MakeTreeNode(dd, 0, 4, MTR_DEFAULT); + REQUIRE(tree != nullptr); + + // Free the tree explicitly + Cudd_FreeTree(dd); + REQUIRE(Cudd_ReadTree(dd) == nullptr); + + Cudd_Quit(dd); + } + + SECTION("Set ZDD tree with actual tree node") { + DdManager *dd = Cudd_Init(0, 4, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + // Create a ZDD tree node + MtrNode *tree = Cudd_MakeZddTreeNode(dd, 0, 4, MTR_DEFAULT); + REQUIRE(tree != nullptr); + + // Free the ZDD tree explicitly + Cudd_FreeZddTree(dd); + REQUIRE(Cudd_ReadZddTree(dd) == nullptr); + + Cudd_Quit(dd); + } + + SECTION("Replace existing tree") { + DdManager *dd = Cudd_Init(4, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + // Create first tree + MtrNode *tree1 = Cudd_MakeTreeNode(dd, 0, 2, MTR_DEFAULT); + REQUIRE(tree1 != nullptr); + + // Create second tree (this should replace the first) + MtrNode *tree2 = Cudd_MakeTreeNode(dd, 2, 2, MTR_DEFAULT); + REQUIRE(tree2 != nullptr); + + Cudd_Quit(dd); + } +} + +// ============================================================================ +// Additional ReadZddOne Tests +// ============================================================================ + +TEST_CASE("ReadZddOne extended tests", "[cuddAPI]") { + DdManager *dd = Cudd_Init(0, 5, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + SECTION("Valid indices") { + for (int i = 0; i <= 5; i++) { + DdNode *zddOne = Cudd_ReadZddOne(dd, i); + REQUIRE(zddOne != nullptr); + } + } + + SECTION("Index equal to sizeZ") { + DdNode *zddOne = Cudd_ReadZddOne(dd, 5); + REQUIRE(zddOne != nullptr); + } + + Cudd_Quit(dd); +} + +// ============================================================================ +// Reordering with Different Methods +// ============================================================================ + +TEST_CASE("Reordering status with various methods", "[cuddAPI]") { + DdManager *dd = Cudd_Init(5, 5, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + SECTION("Test CUDD_REORDER_NONE") { + Cudd_AutodynEnable(dd, CUDD_REORDER_NONE); + Cudd_ReorderingType method; + Cudd_ReorderingStatus(dd, &method); + // CUDD_REORDER_NONE disables reordering + } + + SECTION("Test various reorder methods") { + Cudd_ReorderingType methods[] = { + CUDD_REORDER_RANDOM, + CUDD_REORDER_RANDOM_PIVOT, + CUDD_REORDER_SIFT, + CUDD_REORDER_SIFT_CONVERGE, + CUDD_REORDER_SYMM_SIFT, + CUDD_REORDER_SYMM_SIFT_CONV, + CUDD_REORDER_WINDOW2, + CUDD_REORDER_WINDOW3, + CUDD_REORDER_WINDOW4, + CUDD_REORDER_WINDOW2_CONV, + CUDD_REORDER_WINDOW3_CONV, + CUDD_REORDER_WINDOW4_CONV, + CUDD_REORDER_GROUP_SIFT, + CUDD_REORDER_GROUP_SIFT_CONV, + CUDD_REORDER_ANNEALING, + CUDD_REORDER_GENETIC, + CUDD_REORDER_LINEAR, + CUDD_REORDER_LINEAR_CONVERGE, + CUDD_REORDER_LAZY_SIFT, + CUDD_REORDER_EXACT + }; + + for (auto method : methods) { + Cudd_AutodynEnable(dd, method); + Cudd_ReorderingType readMethod; + int status = Cudd_ReorderingStatus(dd, &readMethod); + REQUIRE(status == 1); + REQUIRE(readMethod == method); + Cudd_AutodynDisable(dd); + } + } + + SECTION("ZDD reordering methods") { + Cudd_AutodynEnableZdd(dd, CUDD_REORDER_SIFT); + Cudd_ReorderingType method; + int status = Cudd_ReorderingStatusZdd(dd, &method); + REQUIRE(status == 1); + REQUIRE(method == CUDD_REORDER_SIFT); + Cudd_AutodynDisableZdd(dd); + } + + Cudd_Quit(dd); +} + +// ============================================================================ +// Variable Attributes Extended Tests +// ============================================================================ + +TEST_CASE("Variable attributes comprehensive tests", "[cuddAPI]") { + DdManager *dd = Cudd_Init(10, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + SECTION("Set all variable types") { + // Set different types for different variables + REQUIRE(Cudd_bddSetPiVar(dd, 0) == 1); + REQUIRE(Cudd_bddSetPsVar(dd, 1) == 1); + REQUIRE(Cudd_bddSetNsVar(dd, 2) == 1); + + // Verify types + REQUIRE(Cudd_bddIsPiVar(dd, 0) == 1); + REQUIRE(Cudd_bddIsPsVar(dd, 1) == 1); + REQUIRE(Cudd_bddIsNsVar(dd, 2) == 1); + + // Cross-check: each var should not be of other types + REQUIRE(Cudd_bddIsPsVar(dd, 0) == 0); + REQUIRE(Cudd_bddIsNsVar(dd, 0) == 0); + } + + SECTION("Pair index operations") { + REQUIRE(Cudd_bddSetPairIndex(dd, 0, 5) == 1); + REQUIRE(Cudd_bddReadPairIndex(dd, 0) == 5); + + REQUIRE(Cudd_bddSetPairIndex(dd, 1, 6) == 1); + REQUIRE(Cudd_bddReadPairIndex(dd, 1) == 6); + } + + SECTION("Grouping operations") { + // Set variables to be grouped + REQUIRE(Cudd_bddSetVarToBeGrouped(dd, 3) == 1); + REQUIRE(Cudd_bddIsVarToBeGrouped(dd, 3) == 1); + + // Set hard group + REQUIRE(Cudd_bddSetVarHardGroup(dd, 4) == 1); + REQUIRE(Cudd_bddIsVarHardGroup(dd, 4) == 1); + + // Set var to be ungrouped + REQUIRE(Cudd_bddSetVarToBeUngrouped(dd, 5) == 1); + REQUIRE(Cudd_bddIsVarToBeUngrouped(dd, 5) == 1); + + // Reset var to be grouped + REQUIRE(Cudd_bddResetVarToBeGrouped(dd, 3) == 1); + } + + SECTION("Binding multiple variables") { + for (int i = 0; i < 5; i++) { + REQUIRE(Cudd_bddBindVar(dd, i) == 1); + REQUIRE(Cudd_bddVarIsBound(dd, i) == 1); + } + + for (int i = 0; i < 5; i++) { + REQUIRE(Cudd_bddUnbindVar(dd, i) == 1); + REQUIRE(Cudd_bddVarIsBound(dd, i) == 0); + } + } + + Cudd_Quit(dd); +} + +// ============================================================================ +// Cache and Memory Extended Tests +// ============================================================================ + +TEST_CASE("Cache and memory operations extended", "[cuddAPI]") { + DdManager *dd = Cudd_Init(10, 5, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + // Perform some operations to use the cache + DdNode *vars[10]; + for (int i = 0; i < 10; i++) { + vars[i] = Cudd_bddIthVar(dd, i); + Cudd_Ref(vars[i]); + } + + // Build some BDDs to exercise the cache + DdNode *result = Cudd_ReadOne(dd); + Cudd_Ref(result); + for (int i = 0; i < 5; i++) { + DdNode *temp = Cudd_bddAnd(dd, result, vars[i]); + Cudd_Ref(temp); + Cudd_RecursiveDeref(dd, result); + result = temp; + } + + // Now read cache statistics + double lookups = Cudd_ReadCacheLookUps(dd); + double hits = Cudd_ReadCacheHits(dd); + unsigned int slots = Cudd_ReadCacheSlots(dd); + double usedSlots = Cudd_ReadCacheUsedSlots(dd); + + REQUIRE(slots > 0); + REQUIRE(lookups >= 0); + REQUIRE(usedSlots >= 0); + + // Memory usage + size_t memUsed = Cudd_ReadMemoryInUse(dd); + REQUIRE(memUsed > 0); + + // Cleanup + Cudd_RecursiveDeref(dd, result); + for (int i = 0; i < 10; i++) { + Cudd_RecursiveDeref(dd, vars[i]); + } + + Cudd_Quit(dd); +} + +// ============================================================================ +// Node Count Functions +// ============================================================================ + +TEST_CASE("Node count functions", "[cuddAPI]") { + DdManager *dd = Cudd_Init(5, 3, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + // Create some BDDs + DdNode *var0 = Cudd_bddIthVar(dd, 0); + DdNode *var1 = Cudd_bddIthVar(dd, 1); + Cudd_Ref(var0); + Cudd_Ref(var1); + + DdNode *andResult = Cudd_bddAnd(dd, var0, var1); + Cudd_Ref(andResult); + + // Check node counts + long nodeCount = Cudd_ReadNodeCount(dd); + REQUIRE(nodeCount >= 0); + + long peakCount = Cudd_ReadPeakNodeCount(dd); + REQUIRE(peakCount >= 0); + + int peakLive = Cudd_ReadPeakLiveNodeCount(dd); + REQUIRE(peakLive >= 0); + + // ZDD node count + long zddCount = Cudd_zddReadNodeCount(dd); + REQUIRE(zddCount >= 0); + + // Cleanup + Cudd_RecursiveDeref(dd, andResult); + Cudd_RecursiveDeref(dd, var0); + Cudd_RecursiveDeref(dd, var1); + + Cudd_Quit(dd); +} + +// ============================================================================ +// Slot and Key Statistics +// ============================================================================ + +TEST_CASE("Slot and key statistics", "[cuddAPI]") { + DdManager *dd = Cudd_Init(5, 3, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + unsigned int slots = Cudd_ReadSlots(dd); + REQUIRE(slots > 0); + + double usedSlots = Cudd_ReadUsedSlots(dd); + REQUIRE(usedSlots >= 0.0); + REQUIRE(usedSlots <= 1.0); + + double expectedUsed = Cudd_ExpectedUsedSlots(dd); + REQUIRE(expectedUsed >= 0.0); + REQUIRE(expectedUsed <= 1.0); + + unsigned int keys = Cudd_ReadKeys(dd); + REQUIRE(keys > 0); + + unsigned int dead = Cudd_ReadDead(dd); + REQUIRE(dead >= 0); + + unsigned int minDead = Cudd_ReadMinDead(dd); + REQUIRE(minDead >= 0); + + Cudd_Quit(dd); +} + +// ============================================================================ +// Reordering Statistics +// ============================================================================ + +TEST_CASE("Reordering statistics", "[cuddAPI]") { + DdManager *dd = Cudd_Init(5, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + unsigned int reorderings = Cudd_ReadReorderings(dd); + REQUIRE(reorderings >= 0); + + long reorderTime = Cudd_ReadReorderingTime(dd); + REQUIRE(reorderTime >= 0); + + unsigned int maxReorderings = Cudd_ReadMaxReorderings(dd); + + // Set and read max reorderings + Cudd_SetMaxReorderings(dd, 50); + REQUIRE(Cudd_ReadMaxReorderings(dd) == 50); + + // Read next reordering threshold + unsigned int nextReorder = Cudd_ReadNextReordering(dd); + REQUIRE(nextReorder > 0); + + // Set next reordering + Cudd_SetNextReordering(dd, 5000); + REQUIRE(Cudd_ReadNextReordering(dd) == 5000); + + Cudd_Quit(dd); +} + +// ============================================================================ +// Garbage Collection Statistics +// ============================================================================ + +TEST_CASE("Garbage collection statistics", "[cuddAPI]") { + DdManager *dd = Cudd_Init(5, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + REQUIRE(dd != nullptr); + + int gcCount = Cudd_ReadGarbageCollections(dd); + REQUIRE(gcCount >= 0); + + long gcTime = Cudd_ReadGarbageCollectionTime(dd); + REQUIRE(gcTime >= 0); + + // Nodes freed/dropped (may return -1 if DD_STATS not defined) + double nodesFreed = Cudd_ReadNodesFreed(dd); + double nodesDropped = Cudd_ReadNodesDropped(dd); + + // Recursive calls (may return -1 if DD_COUNT not defined) + double recursiveCalls = Cudd_ReadRecursiveCalls(dd); + + // Swap steps (may return -1 if DD_COUNT not defined) + double swapSteps = Cudd_ReadSwapSteps(dd); + + // Unique table stats (may return -1 if DD_UNIQUE_PROFILE not defined) + double uniqueLookUps = Cudd_ReadUniqueLookUps(dd); + double uniqueLinks = Cudd_ReadUniqueLinks(dd); + + Cudd_Quit(dd); +} From 47386d863b9585bb97f7be1a4111fc8e0f0d28ac Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 29 Nov 2025 17:49:05 +0000 Subject: [PATCH 5/5] Fix Manager info read test to handle conditionally compiled stats functions Co-authored-by: doganulus <1174212+doganulus@users.noreply.github.com> --- tests/cuddAPI.test.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/tests/cuddAPI.test.cpp b/tests/cuddAPI.test.cpp index a74d1d99..45250a9c 100644 --- a/tests/cuddAPI.test.cpp +++ b/tests/cuddAPI.test.cpp @@ -436,17 +436,27 @@ TEST_CASE("Manager info read functions", "[cuddAPI]") { REQUIRE(Cudd_ReadReorderingTime(dd) >= 0); REQUIRE(Cudd_ReadGarbageCollections(dd) >= 0); REQUIRE(Cudd_ReadGarbageCollectionTime(dd) >= 0); - REQUIRE(Cudd_ReadRecursiveCalls(dd) != 0); - REQUIRE(Cudd_ReadNodesFreed(dd) != 0); - REQUIRE(Cudd_ReadNodesDropped(dd) != 0); - REQUIRE(Cudd_ReadUniqueLookUps(dd) != 0); - REQUIRE(Cudd_ReadUniqueLinks(dd) != 0); + // These functions return -1.0 when DD_COUNT is not defined (feature disabled) + double recursiveCalls = Cudd_ReadRecursiveCalls(dd); + REQUIRE((recursiveCalls == -1.0 || recursiveCalls >= 0.0)); + // These functions return -1.0 when DD_STATS is not defined (feature disabled) + double nodesFreed = Cudd_ReadNodesFreed(dd); + REQUIRE((nodesFreed == -1.0 || nodesFreed >= 0.0)); + double nodesDropped = Cudd_ReadNodesDropped(dd); + REQUIRE((nodesDropped == -1.0 || nodesDropped >= 0.0)); + // These functions return -1.0 when DD_UNIQUE_PROFILE is not defined (feature disabled) + double uniqueLookUps = Cudd_ReadUniqueLookUps(dd); + REQUIRE((uniqueLookUps == -1.0 || uniqueLookUps >= 0.0)); + double uniqueLinks = Cudd_ReadUniqueLinks(dd); + REQUIRE((uniqueLinks == -1.0 || uniqueLinks >= 0.0)); REQUIRE(Cudd_ReadMemoryInUse(dd) > 0); REQUIRE(Cudd_ReadPeakNodeCount(dd) > 0); REQUIRE(Cudd_ReadPeakLiveNodeCount(dd) > 0); REQUIRE(Cudd_ReadNodeCount(dd) >= 0); REQUIRE(Cudd_zddReadNodeCount(dd) >= 0); - REQUIRE(Cudd_ReadSwapSteps(dd) != 0); + // Returns -1.0 when DD_COUNT is not defined + double swapSteps = Cudd_ReadSwapSteps(dd); + REQUIRE((swapSteps == -1.0 || swapSteps >= 0.0)); Cudd_SetMaxReorderings(dd, 100); REQUIRE(Cudd_ReadMaxReorderings(dd) == 100);