You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

1256 lines
47 KiB

/**
@file
@ingroup cudd
@brief Internal data structures of the CUDD package.
@author Fabio Somenzi
@copyright@parblock
Copyright (c) 1995-2015, Regents of the University of Colorado
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
Neither the name of the University of Colorado nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
@endparblock
*/
#ifndef CUDD_INT_H_
#define CUDD_INT_H_
/*---------------------------------------------------------------------------*/
/* Nested includes */
/*---------------------------------------------------------------------------*/
#include <math.h>
#include "config.h"
#include "st.h"
#include "mtr.h"
#include "epd.h"
#include "cudd.h"
/*---------------------------------------------------------------------------*/
/* Constant declarations */
/*---------------------------------------------------------------------------*/
#define CUDD_VERSION PACKAGE_VERSION
#define DD_MAXREF ((DdHalfWord) ~0)
#define DD_DEFAULT_RESIZE 10 /* how many extra variables */
/* should be added when resizing */
#define DD_MEM_CHUNK 1022
/* These definitions work for CUDD_VALUE_TYPE == double */
#define DD_ONE_VAL (1.0)
#define DD_ZERO_VAL (0.0)
#define DD_EPSILON (1.0e-12)
/* The definitions of +/- infinity in terms of HUGE_VAL work on
** the DECstations and on many other combinations of OS/compiler.
*/
#ifdef HAVE_IEEE_754
# define DD_PLUS_INF_VAL (HUGE_VAL)
#else
# define DD_PLUS_INF_VAL (10e301)
# define DD_CRI_HI_MARK (10e150)
# define DD_CRI_LO_MARK (-(DD_CRI_HI_MARK))
#endif
#define DD_MINUS_INF_VAL (-(DD_PLUS_INF_VAL))
#define DD_NON_CONSTANT ((DdNode *) 1) /* for Cudd_bddIteConstant */
/* Unique table and cache management constants. */
#define DD_MAX_SUBTABLE_DENSITY 4 /* tells when to resize a subtable */
/* gc when this percent are dead (measured w.r.t. slots, not keys)
** The first limit (LO) applies normally. The second limit applies when
** the package believes more space for the unique table (i.e., more dead
** nodes) would improve performance, and the unique table is not already
** too large. The third limit applies when memory is low.
*/
#define DD_GC_FRAC_LO DD_MAX_SUBTABLE_DENSITY * 0.25
#define DD_GC_FRAC_HI DD_MAX_SUBTABLE_DENSITY * 1.0
#define DD_GC_FRAC_MIN 0.2
#define DD_MIN_HIT 30 /* resize cache when hit ratio
above this percentage (default) */
#define DD_MAX_LOOSE_FRACTION 5 /* 1 / (max fraction of memory used for
unique table in fast growth mode) */
#define DD_MAX_CACHE_FRACTION 3 /* 1 / (max fraction of memory used for
computed table if resizing enabled) */
#define DD_STASH_FRACTION 64 /* 1 / (fraction of memory set
aside for emergencies) */
#define DD_MAX_CACHE_TO_SLOTS_RATIO 4 /* used to limit the cache size */
/* Variable ordering default parameter values. */
#define DD_SIFT_MAX_VAR 1000
#define DD_SIFT_MAX_SWAPS 2000000
#define DD_DEFAULT_RECOMB 0
#define DD_MAX_REORDER_GROWTH 1.2
#define DD_FIRST_REORDER 4004 /* 4 for the constants */
#define DD_DYN_RATIO 2 /* when to dynamically reorder */
/* Primes for cache hash functions. */
#define DD_P1 12582917
#define DD_P2 4256249
#define DD_P3 741457
#define DD_P4 1618033999
/* Cache tags for 3-operand operators. These tags are stored in the
** least significant bits of the cache operand pointers according to
** the following scheme. The tag consists of two hex digits. Both digits
** must be even, so that they do not interfere with complementation bits.
** The least significant one is stored in Bits 3:1 of the f operand in the
** cache entry. Bit 1 is always 1, so that we can differentiate
** three-operand operations from one- and two-operand operations.
** Therefore, the least significant digit is one of {2,6,a,e}. The most
** significant digit occupies Bits 3:1 of the g operand in the cache
** entry. It can by any even digit between 0 and e. This gives a total
** of 5 bits for the tag proper, which means a maximum of 32 three-operand
** operations. */
#define DD_ADD_ITE_TAG 0x02
#define DD_BDD_AND_ABSTRACT_TAG 0x06
#define DD_BDD_XOR_EXIST_ABSTRACT_TAG 0x0a
#define DD_BDD_ITE_TAG 0x0e
#define DD_ADD_BDD_DO_INTERVAL_TAG 0x22
#define DD_BDD_CLIPPING_AND_ABSTRACT_UP_TAG 0x26
#define DD_BDD_CLIPPING_AND_ABSTRACT_DOWN_TAG 0x2a
#define DD_BDD_COMPOSE_RECUR_TAG 0x2e
#define DD_ADD_COMPOSE_RECUR_TAG 0x42
#define DD_ADD_NON_SIM_COMPOSE_TAG 0x46
#define DD_EQUIV_DC_TAG 0x4a
#define DD_ZDD_ITE_TAG 0x4e
#define DD_ADD_ITE_CONSTANT_TAG 0x62
#define DD_ADD_EVAL_CONST_TAG 0x66
#define DD_BDD_ITE_CONSTANT_TAG 0x6a
#define DD_ADD_OUT_SUM_TAG 0x6e
#define DD_BDD_LEQ_UNLESS_TAG 0x82
#define DD_ADD_TRIANGLE_TAG 0x86
#define DD_BDD_MAX_EXP_TAG 0x8a
#define DD_VARS_SYMM_BEFORE_TAG 0x8e
#define DD_VARS_SYMM_BETWEEN_TAG 0xa2
/* Generator constants. */
#define CUDD_GEN_CUBES 0
#define CUDD_GEN_PRIMES 1
#define CUDD_GEN_NODES 2
#define CUDD_GEN_ZDD_PATHS 3
#define CUDD_GEN_EMPTY 0
#define CUDD_GEN_NONEMPTY 1
/**
** @brief Maximum variable index.
**
** @details CUDD_MAXINDEX is defined in such a way that on 32-bit and
** 64-bit machines one can cast an index to (int) without generating
** a negative number.
*/
#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4
#define CUDD_MAXINDEX (((DdHalfWord) ~0) >> 1)
#else
#define CUDD_MAXINDEX ((DdHalfWord) ~0)
#endif
/**
** @brief The index of constant nodes.
**
** @details This is a synonim for CUDD_MAXINDEX.
*/
#define CUDD_CONST_INDEX CUDD_MAXINDEX
/**
** @brief Size of the random number generator shuffle table.
*/
#define STAB_SIZE 64
/**
** @brief Mask for periodic check of termination and timeout.
**
** @see checkWhetherToGiveUp
*/
#define CUDD_CHECK_MASK 0x7ff
/*---------------------------------------------------------------------------*/
/* Type declarations */
/*---------------------------------------------------------------------------*/
/**
@brief Type that is half the size of a pointer.
*/
#if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4
typedef uint32_t DdHalfWord;
#else
typedef uint16_t DdHalfWord;
#endif
/**
* @brief Signed integer that is the size of a pointer.
*
* @details The only platforms on which CUDD has been tested define
* intptr_t and uintptr_t in inttypes.h and satisfy the condition
*
* sizeof(intptr_t) == sizeof(uintptr_t) == sizeof(void *)
*
* Neither of these is guaranteed by the C standard.
*/
typedef intptr_t ptrint;
/**
* @brief Unsigned integer that is the size of a pointer.
*
* @see ptrint
*/
typedef uintptr_t ptruint;
typedef struct DdChildren DdChildren;
typedef struct DdHook DdHook;
typedef struct DdSubtable DdSubtable;
typedef struct DdCache DdCache;
typedef struct DdLocalCacheItem DdLocalCacheItem;
typedef struct DdLocalCache DdLocalCache;
typedef struct DdHashItem DdHashItem;
typedef struct DdHashTable DdHashTable;
typedef struct Move Move;
typedef struct IndexKey IndexKey;
typedef struct DdQueueItem DdQueueItem;
typedef struct DdLevelQueue DdLevelQueue;
/*---------------------------------------------------------------------------*/
/* Stucture declarations */
/*---------------------------------------------------------------------------*/
/**
* @brief The two children of a non-terminal node.
*/
struct DdChildren {
struct DdNode *T; /**< then (true) child */
struct DdNode *E; /**< else (false) child */
};
/**
* @brief Decision diagram node.
*/
struct DdNode {
DdHalfWord index; /**< variable index */
DdHalfWord ref; /**< reference count */
DdNode *next; /**< next pointer for unique table */
union {
CUDD_VALUE_TYPE value; /**< for constant (terminal) nodes */
DdChildren kids; /**< for internal nodes */
} type; /**< terminal or internal */
};
/**
* @brief CUDD generator.
*/
struct DdGen {
DdManager *manager;
int type;
int status;
union {
struct {
int *cube;
CUDD_VALUE_TYPE value;
} cubes;
struct {
int *cube;
DdNode *ub;
} primes;
struct {
int size;
} nodes;
} gen;
struct {
int sp;
DdNode **stack;
} stack;
DdNode *node;
};
/**
** @brief CUDD hook
**
** Hooks in CUDD are functions that the application registers with the
** manager so that they are called at appropriate times. The functions
** are passed the manager as argument; they should return 1 if
** successful and 0 otherwise.
*/
struct DdHook {
DD_HFP f; /**< function to be called */
struct DdHook *next; /**< next element in the list */
};
/**
* @brief Generic local cache item.
*/
struct DdLocalCacheItem {
DdNode *value;
#ifdef DD_CACHE_PROFILE
ptrint count;
#endif
DdNode *key[1];
};
/**
* @brief Local cache.
*/
struct DdLocalCache {
DdLocalCacheItem *item;
unsigned int itemsize;
unsigned int keysize;
unsigned int slots;
int shift;
double lookUps;
double minHit;
double hits; HTTP/1.1 200 OK Set-Cookie: i_like_gitea=62c220e0265d31d3; Path=/; HttpOnly; SameSite=Lax Set-Cookie: _csrf=V2tIGyiO5Zm6oeNlXRoUgyC074o6MTc2NDE0OTY3NjgyODE0MjYyMQ; Path=/; Expires=Thu, 27 Nov 2025 09:34:36 GMT; HttpOnly; SameSite=Lax Set-Cookie: macaron_flash=; Path=/; Max-Age=0; HttpOnly; SameSite=Lax X-Frame-Options: SAMEORIGIN Date: Wed, 26 Nov 2025 09:34:39 GMT Content-Type: text/plain; charset=utf-8 Transfer-Encoding: chunked 1731 From 291f120cc0cc802aa01a9969aa39e05d4255829d Mon Sep 17 00:00:00 2001 From: PBerger Date: Tue, 26 Jul 2016 14:20:09 +0200 Subject: [PATCH] Added the encoding and identity test for Rational Functions. Former-commit-id: ed9695a5e235196e67158d4b1051b85ef374afda --- test/functional/storage/SylvanDdTest.cpp | 80 +++++++++++++++++------- 1 file changed, 58 insertions(+), 22 deletions(-) diff --git a/test/functional/storage/SylvanDdTest.cpp b/test/functional/storage/SylvanDdTest.cpp index 75a2c8947..ad5566050 100644 --- a/test/functional/storage/SylvanDdTest.cpp +++ b/test/functional/storage/SylvanDdTest.cpp @@ -41,6 +41,46 @@ TEST(SylvanDd, Constants) { EXPECT_EQ(2, two.getMax()); } +TEST(SylvanDd, AddGetMetaVariableTest) { + std::shared_ptr> manager(new storm::dd::DdManager()); + ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9)); + EXPECT_EQ(2ul, manager->getNumberOfMetaVariables()); + + ASSERT_THROW(manager->addMetaVariable("x", 0, 3), storm::exceptions::InvalidArgumentException); + + ASSERT_NO_THROW(manager->addMetaVariable("y", 0, 3)); + EXPECT_EQ(4ul, manager->getNumberOfMetaVariables()); + + EXPECT_TRUE(manager->hasMetaVariable("x'")); + EXPECT_TRUE(manager->hasMetaVariable("y'")); + + std::set metaVariableSet = {"x", "x'", "y", "y'"}; + EXPECT_EQ(metaVariableSet, manager->getAllMetaVariableNames()); +} + +TEST(SylvanDd, EncodingTest) { + std::shared_ptr> manager(new storm::dd::DdManager()); + std::pair x = manager->addMetaVariable("x", 1, 9); + + storm::dd::Bdd encoding; + ASSERT_THROW(encoding = manager->getEncoding(x.first, 0), storm::exceptions::InvalidArgumentException); + ASSERT_THROW(encoding = manager->getEncoding(x.first, 10), storm::exceptions::InvalidArgumentException); + ASSERT_NO_THROW(encoding = manager->getEncoding(x.first, 4)); + EXPECT_EQ(1ul, encoding.getNonZeroCount()); + + // As a BDD, this DD has one only leaf, because there does not exist a 0-leaf, and (consequently) one node less + // than the MTBDD. + EXPECT_EQ(5ul, encoding.getNodeCount()); + EXPECT_EQ(1ul, encoding.getLeafCount()); + + storm::dd::Add add; + ASSERT_NO_THROW(add = encoding.template toAdd()); + + // As an MTBDD, the 0-leaf is there, so the count is actually 2 and the node count is 6. + EXPECT_EQ(6ul, add.getNodeCount()); + EXPECT_EQ(2ul, add.getLeafCount()); +} + #ifdef STORM_HAVE_CARL TEST(SylvanDd, RationalFunctionConstants) { std::shared_ptr> manager(new storm::dd::DdManager()); @@ -67,26 +107,8 @@ TEST(SylvanDd, RationalFunctionConstants) { EXPECT_EQ(1ul, two.getLeafCount()); EXPECT_EQ(1ul, two.getNodeCount()); } -#endif - -TEST(SylvanDd, AddGetMetaVariableTest) { - std::shared_ptr> manager(new storm::dd::DdManager()); - ASSERT_NO_THROW(manager->addMetaVariable("x", 1, 9)); - EXPECT_EQ(2ul, manager->getNumberOfMetaVariables()); - - ASSERT_THROW(manager->addMetaVariable("x", 0, 3), storm::exceptions::InvalidArgumentException); - - ASSERT_NO_THROW(manager->addMetaVariable("y", 0, 3)); - EXPECT_EQ(4ul, manager->getNumberOfMetaVariables()); - - EXPECT_TRUE(manager->hasMetaVariable("x'")); - EXPECT_TRUE(manager->hasMetaVariable("y'")); - - std::set metaVariableSet = {"x", "x'", "y", "y'"}; - EXPECT_EQ(metaVariableSet, manager->getAllMetaVariableNames()); -} -TEST(SylvanDd, EncodingTest) { +TEST(SylvanDd, RationalFunctionEncodingTest) { std::shared_ptr> manager(new storm::dd::DdManager()); std::pair x = manager->addMetaVariable("x", 1, 9); @@ -101,14 +123,28 @@ TEST(SylvanDd, EncodingTest) { EXPECT_EQ(5ul, encoding.getNodeCount()); EXPECT_EQ(1ul, encoding.getLeafCount()); - storm::dd::Add add; - ASSERT_NO_THROW(add = encoding.template toAdd()); + storm::dd::Add add; + ASSERT_NO_THROW(add = encoding.template toAdd()); // As an MTBDD, the 0-leaf is there, so the count is actually 2 and the node count is 6. EXPECT_EQ(6ul, add.getNodeCount()); EXPECT_EQ(2ul, add.getLeafCount()); } +TEST(SylvanDd, RationalFunctionIdentityTest) { + std::shared_ptr> manager(new storm::dd::DdManager()); + std::pair x = manager->addMetaVariable("x", 1, 9); + + storm::dd::Add identity; + ASSERT_NO_THROW(identity = manager->getIdentity(x.first)); + + EXPECT_EQ(9ul, identity.getNonZeroCount()); + EXPECT_EQ(10ul, identity.getLeafCount()); + EXPECT_EQ(21ul, identity.getNodeCount()); +} + +#endif + TEST(SylvanDd, RangeTest) { std::shared_ptr> manager(new storm::dd::DdManager()); std::pair x; @@ -440,4 +476,4 @@ TEST(SylvanDd, BddOddTest) { EXPECT_EQ(9ul, matrix.getRowGroupCount()); EXPECT_EQ(9ul, matrix.getColumnCount()); EXPECT_EQ(106ul, matrix.getNonzeroEntryCount()); -} \ No newline at end of file +} 0 HTTP/1.0 200 OK Content-Type: text/html; charset=UTF-8 Set-Cookie: i_like_gitea=8cd0a7e1bd6800f7; Path=/; HttpOnly; SameSite=Lax Set-Cookie: _csrf=TIditkkL92FIyC-vuMmWQ6_fZNk6MTc2NDE0OTY3MzgwNjg5NTE1OA; Path=/; Expires=Thu, 27 Nov 2025 09:34:33 GMT; HttpOnly; SameSite=Lax Set-Cookie: macaron_flash=; Path=/; Max-Age=0; HttpOnly; SameSite=Lax X-Frame-Options: SAMEORIGIN Date: Wed, 26 Nov 2025 09:34:39 GMT sp/tempest - tempest - Gitea: Git with a cup of tea