Giter Site home page Giter Site logo

cl-cudd's Introduction

Common Lisp binding to CUDD Build Status

This is a fork of original CL-CUDD using the modern common lisp convension.

  • Supported implementations: SBCL, CCL and ECL.
  • Requirements: make, curl
  • Developmental State: After some refurbishment, now it loads reliably and all tests pass.
  • TODOs:
    • Automatic variable reordering
    • Variable grouping API
    • GC hook and control API
    • Higher-order layer for set manipulation
    • benchmarking
  • Related work: trivialib.bdd is another common lisp library for BDDs, which is entirely written in lisp. CUDD is more on the state-of-the-art side.

What is BDDs and CUDD?

BDDs (Binary Decision Diagrams) are awesome datastructures that can compactly represent exponentially large number of datasets, as well as allowing the direct computation over the compressed representation, i.e., you can take the sum/product/union/intersection of the datasets without decompressing the data!

CUDD is a famous C implementation of BDDs and its relatives: Multi-Terminal Binary Decision Diagrams (MTBDDs, also known as Algebraic DD / ADDs) and Zero-suppressed Decision Diagrams.

References:

trivialib.bdd is another common lisp library for BDDs, which is entirely written in lisp. CUDD is more on the state-of-the-art side.

Building/Loading the system

The system is asdf-loadable. This version of CL-CUDD automatically fetches CUDD v3.0.0 from http://vlsi.colorado.edu/~fabio/CUDD/ via curl. The archive is expanded in the ASDF system directory and builds its dynamic library, which is then loaded by CL-CUDD.

To test the system, evaluate (asdf:test-system :cl-cudd.test). It also writes the visualizations of the decision diagrams to the system directory in DOT format. If you have Graphviz installed, the test script also tries to convert the results into pdfs.

The binding(s)

The binding consists of two layers: The lower layer has cl-cudd.baseapi package. This layer is a very thin wrapper around the C library, passes raw pointers around and requires that you take care of reference counting.

Above this layer there is a package named cl-cudd (with a nickname cudd). It wraps the pointers from the lower layer, takes care of reference counting for you, defines several high-level operations, and also adds documentation from the CUDD manual.

DD Construction Examples

See EXAMPLES.md.

System structure

Low-level

This is loosely based on the SWIG-extracted information and is using CFFI-Grovel to actually map C symbols to lisp symbols. If you want to use this layer, then it would be best to have a look at the CUDD manual.

You can use the low-level system just as you would use the C API of CUDD. This also means that you have to do all the reference counting yourself, with one exception: The reference count of the return value each CUDD function that returns a node is increased if it is not null. If it is null, a signal of type cudd-null-pointer-error is raised.

High-level

The high level API automatically wraps the CUDD nodes in an instance of class node. ADD nodes are wrapped in an instance of add-node and BDD nodes are wrapped in an instance of type bdd-node.

This enables runtime type checking (so that you don't stick ADD nodes into BDD functions or vice-versa) and also automatic reference counting.

Almost all CUDD functions need to refer to a CUDD manager. In the high-level API this manager is contained in special variable *manager*. You can bind a manager using the macro with-manager. You can also create a manager by (make-instance 'manager :pointer (cudd-init 0 0 256 262144 0)).

All functions of package CL-CUDD are documented using the original or slightly modified documentation of CUDD.

History

The initial version was automatically generated using SWIG by Utz-Uwe Haus. The second version was adapted to the needs by Christian von Essen [email protected]. Later, @Neronus made a git repository on Github and @rpgoldman made a few bugfixes. Finally @guicho271828 (Masataro Asai) has modernized the repository according to the recent practice in common lisp: unit tests, Travis-CI support, better documentation and additional support for ZDDs.

Known problems

Using the GC to do reference counting automatically has its own share of problems:

  1. References may be freed very late.

    Nodes will be dereferenced only if your CL implementation thinks that it's time for it. This is usually when itself is running out of memory. Because you are usually only holding on to the top of a diagram, you are not using as much memory in CL as you are using in CUDD. Hence the GC might come pretty late while CUDD is happily accumulating memory.

    The solution to that is to try to call the garbage collector manually every so often using for example TRIVIAL-GARBAGE:GC

Solved problems

References may be freed too early

The old text below is wrong. CUDD's reference counting GC does not work this way. According to CUDD's manual, its GC happens when:

  1. A call to cuddUniqueInter , to cuddUniqueInterZdd , to cuddUnique- Const, or to a function that may eventually cause a call to them.
  2. A call to Cudd RecursiveDeref , to Cudd RecursiveDerefZdd , or to a function that may eventually cause a call to them.

Thus the GC does not occur at arbitrary code path, as assumed below.

 The following two examples demonstrate the problem.

    (defun foo (dd)
      (let ((ptr (node-pointer dd)))
        ;; please don't GC me here
        (cudd-do-something ptr)))

In this example the GC might decide to run where there is the
comment.
In that case, provided that nothing outside of the function call
holds on to `dd`, the reference count of `ptr` might be decreased,
go down to zero and the node vanishes before `cudd-do-something` is
called.

cl-cudd's People

Contributors

guicho271828 avatar neronus avatar rpgoldman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

dumaiu

cl-cudd's Issues

Building fails on OS X

I'm trying to build cl-cudd on OS X. cudd itself builds fine, but something seems broken with the cffi/swig bindings:

--------------------------------------------------
Configuration summary for cudd 3.0.0

Build system   : x86_64-apple-darwin15.3.0
Host system    : x86_64-apple-darwin15.3.0
Prefix         : '/usr/local'
Compilers      : 'gcc    -Wall -Wextra -g -O3'
               : 'g++    -Wall -Wextra -std=c++0x -g -O3'
Shared library : yes
 dddmp enabled : no
 obj enabled   : no
--------------------------------------------------
/Applications/Xcode.app/Contents/Developer/usr/bin/make -C cudd-3.0.0 all-am
; compiling file "/Users/sjl/src/cl-cudd/src/1-1-1-grovel.lisp" (written 25 AUG 2016 01:42:56 PM):
; compiling (IN-PACKAGE :CL-CUDD.BASEAPI)
; compiling (INCLUDE "stdio.h")
; compiling (INCLUDE "stdlib.h")
; compiling (CC-FLAGS "-I/Users/sjl/src/cl-cudd/cudd-3.0.0/build-aux/ -I/Users/sjl/src/cl-cudd/cudd-3.0.0/cplusplus/ -I/Users/sjl/src/cl-cudd/cudd-3.0.0/cudd/ -I/Users/sjl/src/cl-cudd/cudd-3.0.0/dddmp/ -I/Users/sjl/src/cl-cudd/cudd-3.0.0/doc/ -I/Users/sjl/src/cl-cudd/cudd-3.0.0/epd/ -I/Users/sjl/src/cl-cudd/cudd-3.0.0/m4/ -I/Users/sjl/src/cl-cudd/cudd-3.0.0/mtr/ -I/Users/sjl/src/cl-cudd/cudd-3.0.0/nanotrav/ -I/Users/sjl/src/cl-cudd/cudd-3.0.0/st/ -I/Users/sjl/src/cl-cudd/cudd-3.0.0/util/ ")
; compiling (CC-FLAGS "-I/Users/sjl/src/cl-cudd/cudd-3.0.0/")
; compiling (INCLUDE "config.h")
; compiling (INCLUDE "cudd/cudd.h")
; compiling (INCLUDE "cudd/cuddInt.h")
; compiling (CTYPE DD-HALF-WORD ...)
; compiling (CTYPE CUDD-VALUE-TYPE ...)
; compiling (CONSTANT (+CUDD-VERSION+ "CUDD_VERSION"))
; compiling (CONSTANT (+SIZEOF-VOID-P+ "SIZEOF_VOID_P"))
; compiling (CONSTANT (+SIZEOF-INT+ "SIZEOF_INT"))
; compiling (CONSTANT (+SIZEOF-LONG+ "SIZEOF_LONG"))
; compiling (CONSTANT (+TRUE+ "TRUE"))
; compiling (CONSTANT (+FALSE+ "FALSE"))
; compiling (CONSTANT (+CUDD-OUT-OF-MEM+ "CUDD_OUT_OF_MEM"))
; compiling (CONSTANT (+CUDD-UNIQUE-SLOTS+ "CUDD_UNIQUE_SLOTS"))
; compiling (CONSTANT (+CUDD-CACHE-SLOTS+ "CUDD_CACHE_SLOTS"))
; compiling (CONSTANT (+CUDD-RESIDUE-DEFAULT+ "CUDD_RESIDUE_DEFAULT"))
; compiling (CONSTANT (+CUDD-RESIDUE-MSB+ "CUDD_RESIDUE_MSB"))
; compiling (CONSTANT (+CUDD-RESIDUE-TC+ "CUDD_RESIDUE_TC"))
; compiling (CONSTANT (+DD-APA-BITS+ "DD_APA_BITS"))
; compiling (CONSTANT (+DD-APA-BASE+ "DD_APA_BASE"))
; compiling (CONSTANT (+DD-APA-MASK+ "DD_APA_MASK"))
; compiling (CONSTANT (+DD-APA-HEXPRINT+ "DD_APA_HEXPRINT"))
; compiling (CENUM CUDD-REORDERING-TYPE ...)
; file: /Users/sjl/src/cl-cudd/src/1-1-1-grovel.lisp
; in: CENUM CUDD-REORDERING-TYPE
;     ((:+CUDD-REORDER-SAME+ "CUDD_REORDER_SAME"))
;
; caught ERROR:
;   illegal function call

;     ((:+CUDD-REORDER-NONE+ "CUDD_REORDER_NONE"))
;
; caught ERROR:
;   illegal function call

;     ((:+CUDD-REORDER-RANDOM+ "CUDD_REORDER_RANDOM"))
;
; caught ERROR:
;   illegal function call

;     ((:+CUDD-REORDER-RANDOM-PIVOT+ "CUDD_REORDER_RANDOM_PIVOT"))
;
; caught ERROR:
;   illegal function call

;     ((:+CUDD-REORDER-SIFT+ "CUDD_REORDER_SIFT"))
;
; caught ERROR:
;   illegal function call

;     ((:+CUDD-REORDER-SIFT-CONVERGE+ "CUDD_REORDER_SIFT_CONVERGE"))
;
; caught ERROR:
;   illegal function call

;     ((:+CUDD-REORDER-SYMM-SIFT+ "CUDD_REORDER_SYMM_SIFT"))
;
; caught ERROR:
;   illegal function call

;     ((:+CUDD-REORDER-SYMM-SIFT-CONV+ "CUDD_REORDER_SYMM_SIFT_CONV"))
;
; caught ERROR:
;   illegal function call

;     ((:+CUDD-REORDER-WINDOW-2+ "CUDD_REORDER_WINDOW2"))
;
; caught ERROR:
;   illegal function call

;     ((:+CUDD-REORDER-WINDOW-3+ "CUDD_REORDER_WINDOW3"))
;
; caught ERROR:
;   illegal function call

;     ((:+CUDD-REORDER-WINDOW-4+ "CUDD_REORDER_WINDOW4"))
;
; caught ERROR:
;   illegal function call

;     ((:+CUDD-REORDER-WINDOW-2-CONV+ "CUDD_REORDER_WINDOW2_CONV"))
;
; caught ERROR:
;   illegal function call

;     ((:+CUDD-REORDER-WINDOW-3-CONV+ "CUDD_REORDER_WINDOW3_CONV"))
;
; caught ERROR:
;   illegal function call

;     ((:+CUDD-REORDER-WINDOW-4-CONV+ "CUDD_REORDER_WINDOW4_CONV"))
;
; caught ERROR:
;   illegal function call

;     ((:+CUDD-REORDER-GROUP-SIFT+ "CUDD_REORDER_GROUP_SIFT"))
;
; caught ERROR:
;   illegal function call

;     ((:+CUDD-REORDER-GROUP-SIFT-CONV+ "CUDD_REORDER_GROUP_SIFT_CONV"))
;
; caught ERROR:
;   illegal function call

;     ((:+CUDD-REORDER-ANNEALING+ "CUDD_REORDER_ANNEALING"))
;
; caught ERROR:
;   illegal function call

;     ((:+CUDD-REORDER-GENETIC+ "CUDD_REORDER_GENETIC"))
;
; caught ERROR:
;   illegal function call

;     ((:+CUDD-REORDER-LINEAR+ "CUDD_REORDER_LINEAR"))
;
; caught ERROR:
;   illegal function call

;     ((:+CUDD-REORDER-LINEAR-CONVERGE+ "CUDD_REORDER_LINEAR_CONVERGE"))
;
; caught ERROR:
;   illegal function call

;     ((:+CUDD-REORDER-LAZY-SIFT+ "CUDD_REORDER_LAZY_SIFT"))
;
; caught ERROR:
;   illegal function call

;     ((:+CUDD-REORDER-EXACT+ "CUDD_REORDER_EXACT"))
;
; caught ERROR:
;   illegal function call

;     (CL-CUDD.BASEAPI::CENUM CL-CUDD.BASEAPI:CUDD-REORDERING-TYPE
;      ((:+CUDD-REORDER-SAME+ "CUDD_REORDER_SAME"))
;      ((:+CUDD-REORDER-NONE+ "CUDD_REORDER_NONE"))
;      ((:+CUDD-REORDER-RANDOM+ "CUDD_REORDER_RANDOM"))
;      ((:+CUDD-REORDER-RANDOM-PIVOT+ "CUDD_REORDER_RANDOM_PIVOT"))
;      ((:+CUDD-REORDER-SIFT+ "CUDD_REORDER_SIFT"))
;      ((:+CUDD-REORDER-SIFT-CONVERGE+ "CUDD_REORDER_SIFT_CONVERGE"))
;      ((:+CUDD-REORDER-SYMM-SIFT+ "CUDD_REORDER_SYMM_SIFT"))
;      ((:+CUDD-REORDER-SYMM-SIFT-CONV+ "CUDD_REORDER_SYMM_SIFT_CONV"))
;      ((:+CUDD-REORDER-WINDOW-2+ "CUDD_REORDER_WINDOW2"))
;      ((:+CUDD-REORDER-WINDOW-3+ "CUDD_REORDER_WINDOW3")) ...)
;
; note: deleting unreachable code

; compiling (CENUM CUDD-AGGREGATION-TYPE ...)
; file: /Users/sjl/src/cl-cudd/src/1-1-1-grovel.lisp
; in: CENUM CUDD-AGGREGATION-TYPE
;     ((:+CUDD-NO-CHECK+ "CUDD_NO_CHECK"))
;
; caught ERROR:
;   illegal function call

; ... lots more illegal function call complaints ...

I don't really know enough about swig/cffi to debug further.

Taking over

@rpgoldman , apparantly @Neronus seems inactive for years, so I'm considering taking it over.
Now my version pulls the latest CUDD, build it, grovel it and sets up the foreign library. (latest tarball is download by curl, therefore there is no need to install it manually) It also follows a modern style and has an example in the test/ directory.

I'm more interested in using ZDD, so I have to extend the library.

Failure due to ftp issue

curl ftp://vlsi.colorado.edu/pub/cudd-3.0.0.tar.gz times out for me, and that means cl-cudd doesn't build. Is there a way to avoid depending on a university ftp site at build time?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.