├── log ├── empty.and ├── and1.and ├── and2.and ├── and3.and ├── and2.out ├── empty.out ├── toggle.in ├── .gitignore ├── and1.out ├── and3.out ├── init1.blif ├── nextnoinit.smv ├── nonext.smv ├── cnt1.smv ├── regr0.smv ├── cnt1e.smv ├── flip1.smv ├── initinvar0.smv ├── initinvar1.smv ├── cnt2.smv ├── inittrans0.smv ├── inittrans1.smv ├── cnt1re.smv ├── cnt2e.smv ├── cnt3.smv ├── cnt2re.smv ├── cnt4.smv ├── cnt3e.smv ├── cnt3re.smv ├── s27.blif ├── inittrans0det.smv ├── inittrans1det.smv ├── dp2.smv └── dp3.smv ├── VERSION ├── examples ├── empty.aag ├── false.aag ├── true.aag ├── cnt1.wit ├── buffer.aag ├── cnt1.aag ├── inverter.aag ├── cnt1e.wit ├── toggle.aag ├── and.aag ├── or.aag ├── .cvsignore ├── notcnt1.aag ├── xor1.aag ├── smv │ ├── s2cfair.aig │ ├── s2cunfair.aig │ ├── latch1.smv │ ├── mult2.aig │ ├── latch0.smv │ ├── mult2.flatsmv │ ├── latch2.smv │ ├── mult2.smv │ ├── s2cunfair.flatsmv │ ├── s2cunfair.smv │ ├── s2cfair.flatsmv │ └── s2cfair.smv ├── cnt1e.aag ├── notcnt1e.aag ├── makefile ├── halfadder.aag ├── toggle-re.aag ├── xorxormiter.aag └── code │ ├── read.c │ ├── write.c │ ├── JaigerToCNF.java │ └── poormanaigtocnf.c ├── doc ├── aiger1 │ └── makefile └── beyond1 │ ├── makefile │ └── .gitignore ├── cleanaigfuzz ├── testbliftoaig ├── aigvis ├── testall ├── testaigbmc ├── TODO ├── aiginterleave.sh ├── aigdeinterleave.sh ├── verify_bliftoaig ├── aigswap.sh ├── aigswap2.sh ├── .gitignore ├── testandtoaig ├── test.mk ├── runaigmcncheck ├── mkrelease.sh ├── testsmvtoaig ├── mkminrel.sh ├── runaigcnfuzz ├── shrinkaigerwitness.c ├── jku.c ├── aigfuzz.h ├── runaigfuzz ├── aiginfo.c ├── aignm.c ├── README ├── aigstrip.c ├── aiguncomment.c ├── configure.sh ├── mc.sh ├── andtoaig.c ├── aigor.c ├── aigand.c ├── aigflip.c ├── LICENSE ├── NEWS.md ├── makefile.in ├── testsimpaig.c ├── aigreset.c ├── simpaig.h ├── aigtobtor.c ├── aigmove.c ├── aigunconstraint.c ├── soltostim.c ├── wrapstim.c ├── aigtodot.c ├── aigunor.c ├── aigtosmv.c └── testaigtoaig.c /log/empty.and: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 1.9.24 2 | -------------------------------------------------------------------------------- /log/and1.and: -------------------------------------------------------------------------------- 1 | 2 4 6 2 | -------------------------------------------------------------------------------- /log/and2.and: -------------------------------------------------------------------------------- 1 | 2 2 1 2 | -------------------------------------------------------------------------------- /log/and3.and: -------------------------------------------------------------------------------- 1 | 100 2001 11 2 | -------------------------------------------------------------------------------- /examples/empty.aag: -------------------------------------------------------------------------------- 1 | aag 0 0 0 0 0 2 | -------------------------------------------------------------------------------- /examples/false.aag: -------------------------------------------------------------------------------- 1 | aag 0 0 0 1 0 2 | 0 3 | -------------------------------------------------------------------------------- /examples/true.aag: -------------------------------------------------------------------------------- 1 | aag 0 0 0 1 0 2 | 1 3 | -------------------------------------------------------------------------------- /examples/cnt1.wit: -------------------------------------------------------------------------------- 1 | 1 2 | b0 3 | 0 4 | 5 | . 6 | -------------------------------------------------------------------------------- /doc/aiger1/makefile: -------------------------------------------------------------------------------- 1 | all: 2 | pdflatex aiger1 3 | -------------------------------------------------------------------------------- /doc/beyond1/makefile: -------------------------------------------------------------------------------- 1 | all: 2 | pdflatex beyond1 3 | -------------------------------------------------------------------------------- /examples/buffer.aag: -------------------------------------------------------------------------------- 1 | aag 1 1 0 1 0 2 | 2 3 | 2 4 | -------------------------------------------------------------------------------- /examples/cnt1.aag: -------------------------------------------------------------------------------- 1 | aag 1 0 1 0 0 1 2 | 2 3 3 | 2 4 | -------------------------------------------------------------------------------- /examples/inverter.aag: -------------------------------------------------------------------------------- 1 | aag 1 1 0 1 0 2 | 2 3 | 3 4 | -------------------------------------------------------------------------------- /examples/cnt1e.wit: -------------------------------------------------------------------------------- 1 | 1 2 | b0 3 | 0 4 | 1 5 | 1 6 | . 7 | -------------------------------------------------------------------------------- /examples/toggle.aag: -------------------------------------------------------------------------------- 1 | aag 1 0 1 2 0 2 | 2 3 3 | 2 4 | 3 5 | -------------------------------------------------------------------------------- /examples/and.aag: -------------------------------------------------------------------------------- 1 | aag 3 2 0 1 1 2 | 2 3 | 4 4 | 6 5 | 6 2 4 6 | -------------------------------------------------------------------------------- /examples/or.aag: -------------------------------------------------------------------------------- 1 | aag 3 2 0 1 1 2 | 2 3 | 4 4 | 7 5 | 6 3 5 6 | -------------------------------------------------------------------------------- /log/and2.out: -------------------------------------------------------------------------------- 1 | *** [andtoaig] cyclic definition for and gate 1 2 | -------------------------------------------------------------------------------- /log/empty.out: -------------------------------------------------------------------------------- 1 | aag 0 0 0 0 0 2 | c 3 | andtoaig 4 | log/empty.and 5 | -------------------------------------------------------------------------------- /cleanaigfuzz: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | killall runaigmcfuzz 3 | rm -f red-* bug-* 4 | -------------------------------------------------------------------------------- /examples/.cvsignore: -------------------------------------------------------------------------------- 1 | write 2 | read 3 | poormanaigtocnf 4 | *.class 5 | -------------------------------------------------------------------------------- /examples/notcnt1.aag: -------------------------------------------------------------------------------- 1 | aag 1 0 1 0 0 1 2 | 2 3 3 | 3 4 | b0 AIGER_NEVER 5 | -------------------------------------------------------------------------------- /log/toggle.in: -------------------------------------------------------------------------------- 1 | aag 4 1 1 1 2 2 | 2 3 | 4 6 4 | 8 5 | 6 3 5 6 | 8 4 5 7 | -------------------------------------------------------------------------------- /examples/xor1.aag: -------------------------------------------------------------------------------- 1 | aag 5 2 0 1 3 2 | 2 3 | 4 4 | 10 5 | 6 2 4 6 | 8 3 5 7 | 10 7 9 8 | -------------------------------------------------------------------------------- /doc/beyond1/.gitignore: -------------------------------------------------------------------------------- 1 | beyond1.aux 2 | beyond1.log 3 | beyond1.pdf 4 | beyond1.tex.bak 5 | -------------------------------------------------------------------------------- /log/.gitignore: -------------------------------------------------------------------------------- 1 | *.aag 2 | *.aig 3 | *.aag.gz 4 | *.aig.gz 5 | *.smvfromaig 6 | *.log 7 | *.err 8 | -------------------------------------------------------------------------------- /log/and1.out: -------------------------------------------------------------------------------- 1 | aag 3 2 0 1 1 2 | 4 3 | 6 4 | 2 5 | 2 4 6 6 | c 7 | andtoaig 8 | log/and1.and 9 | -------------------------------------------------------------------------------- /examples/smv/s2cfair.aig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arminbiere/aiger/HEAD/examples/smv/s2cfair.aig -------------------------------------------------------------------------------- /examples/smv/s2cunfair.aig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arminbiere/aiger/HEAD/examples/smv/s2cunfair.aig -------------------------------------------------------------------------------- /examples/cnt1e.aag: -------------------------------------------------------------------------------- 1 | aag 5 1 1 0 3 1 2 | 2 3 | 4 10 4 | 4 5 | 6 5 3 6 | 8 4 2 7 | 10 9 7 8 | b0 AIGER_NEVER 9 | -------------------------------------------------------------------------------- /examples/notcnt1e.aag: -------------------------------------------------------------------------------- 1 | aag 5 1 1 0 3 1 2 | 2 3 | 4 10 4 | 5 5 | 6 5 3 6 | 8 4 2 7 | 10 9 7 8 | b0 AIGER_NEVER 9 | -------------------------------------------------------------------------------- /log/and3.out: -------------------------------------------------------------------------------- 1 | aag 1000 2 0 1 1 2 | 10 3 | 2000 4 | 100 5 | 100 2001 11 6 | c 7 | andtoaig 8 | log/and3.and 9 | -------------------------------------------------------------------------------- /log/init1.blif: -------------------------------------------------------------------------------- 1 | .model test 2 | .inputs i 3 | .outputs l 4 | .latch n l 1 5 | .names l i n 6 | 11 1 7 | .end 8 | -------------------------------------------------------------------------------- /log/nextnoinit.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | a : boolean; 4 | ASSIGN 5 | next (a) := a; 6 | SPEC 7 | AG !a 8 | -------------------------------------------------------------------------------- /log/nonext.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | u : boolean; 4 | ASSIGN 5 | init (u) := FALSE; 6 | SPEC 7 | AG !u 8 | -------------------------------------------------------------------------------- /examples/makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-g -Wall 2 | TARGETS=read write poormanaigtocnf 3 | all: $(TARGETS) 4 | clean: 5 | rm -f $(TARGETS) 6 | -------------------------------------------------------------------------------- /log/cnt1.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | x : boolean; 4 | ASSIGN 5 | init (x) := FALSE; 6 | next (x) := !x; 7 | SPEC 8 | AG !x 9 | -------------------------------------------------------------------------------- /testbliftoaig: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ./verify_bliftoaig log/s27.blif 3 | ./verify_bliftoaig log/s713.blif 4 | ./verify_bliftoaig log/s1494.blif 5 | -------------------------------------------------------------------------------- /examples/halfadder.aag: -------------------------------------------------------------------------------- 1 | aag 7 2 0 2 3 2 | 2 3 | 4 4 | 6 5 | 12 6 | 6 13 15 7 | 12 2 4 8 | 14 3 5 9 | i0 x 10 | i1 y 11 | o0 s 12 | o1 c 13 | c 14 | half adder 15 | -------------------------------------------------------------------------------- /examples/toggle-re.aag: -------------------------------------------------------------------------------- 1 | aag 7 2 1 2 4 2 | 2 3 | 4 4 | 6 8 5 | 6 6 | 7 7 | 8 4 10 8 | 10 13 15 9 | 12 2 6 10 | 14 3 7 11 | i0 enable 12 | i1 reset 13 | o0 Q 14 | o1 !Q 15 | -------------------------------------------------------------------------------- /examples/xorxormiter.aag: -------------------------------------------------------------------------------- 1 | aag 11 2 0 1 9 2 | 2 3 | 4 4 | 22 5 | 6 2 4 6 | 8 3 5 7 | 10 7 9 8 | 12 2 5 9 | 14 3 4 10 | 16 13 15 11 | 18 10 17 12 | 20 11 16 13 | 22 19 21 14 | -------------------------------------------------------------------------------- /log/regr0.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | a : boolean; 4 | b : boolean; 5 | DEFINE 6 | ASSIGN 7 | init(b) := TRUE; 8 | INVAR 9 | !a | !b 10 | SPEC 11 | AG (!a | b) 12 | -------------------------------------------------------------------------------- /aigvis: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | tmp="/tmp/aigvis$$" 3 | trap "rm -f $tmp.*" 2 6 11 4 | aigtodot $* > $tmp.dot || exit 1 5 | dot -Tpdf $tmp.dot > $tmp.pdf || exit 1 6 | evince $tmp.pdf 7 | rm -f $tmp.* 8 | -------------------------------------------------------------------------------- /log/cnt1e.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | x : boolean; 4 | e : boolean; 5 | ASSIGN 6 | init (x) := FALSE; 7 | next (x) := case e : !x; TRUE : x; esac; 8 | SPEC 9 | AG !x 10 | -------------------------------------------------------------------------------- /log/flip1.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | input : boolean; 4 | state : boolean; 5 | ASSIGN 6 | init (state) := TRUE; 7 | next (state) := state & input; 8 | SPEC 9 | AG state 10 | -------------------------------------------------------------------------------- /log/initinvar0.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | a : boolean; 4 | b : boolean; 5 | INVAR 6 | a -> b 7 | ASSIGN 8 | init (a) := FALSE; 9 | next (a) := b; 10 | SPEC 11 | AG a = b 12 | -------------------------------------------------------------------------------- /log/initinvar1.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | a : boolean; 4 | b : boolean; 5 | INVAR 6 | b -> a 7 | ASSIGN 8 | init (a) := FALSE; 9 | next (a) := b; 10 | SPEC 11 | AG a = b 12 | -------------------------------------------------------------------------------- /examples/smv/latch1.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | a : boolean; 4 | b : boolean; 5 | ASSIGN 6 | init (a) := TRUE; 7 | init (b) := TRUE; 8 | next (a) := a; 9 | SPEC 10 | AG (a | b) 11 | -------------------------------------------------------------------------------- /log/cnt2.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | x : boolean; 4 | y : boolean; 5 | ASSIGN 6 | init (x) := FALSE; 7 | next (x) := !x; 8 | init (y) := FALSE; 9 | next (y) := y <-> !x; 10 | SPEC 11 | AG !(x & y) 12 | -------------------------------------------------------------------------------- /log/inittrans0.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | a : boolean; 4 | b : boolean; 5 | c : boolean; 6 | INIT 7 | a = c 8 | INIT 9 | b != c 10 | TRANS 11 | (a != b) -> (next(a) != next(b)) 12 | SPEC 13 | AG (a != b) 14 | -------------------------------------------------------------------------------- /log/inittrans1.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | a : boolean; 4 | b : boolean; 5 | c : boolean; 6 | INIT 7 | a = c 8 | INIT 9 | b != c 10 | TRANS 11 | (a = b) -> (next(a) = next(b)) 12 | SPEC 13 | AG (a != b) 14 | -------------------------------------------------------------------------------- /log/cnt1re.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | x : boolean; 4 | e : boolean; 5 | r : boolean; 6 | ASSIGN 7 | init (x) := FALSE; 8 | next (x) := case r : FALSE; TRUE : case e : !x; TRUE : x; esac; esac; 9 | SPEC 10 | AG !x 11 | -------------------------------------------------------------------------------- /testall: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo "[testaigbmc]";./testaigbmc 3 | echo "[testaigtoaig]";./testaigtoaig 4 | echo "[testsimpaig]";./testsimpaig 5 | echo "[testsmvtoaig]";./testsmvtoaig 6 | echo "[testandtoaig]";./testandtoaig 7 | echo "[testbliftoaig]";./testbliftoaig 8 | -------------------------------------------------------------------------------- /examples/smv/mult2.aig: -------------------------------------------------------------------------------- 1 | aig 15 2 2 0 11 2 1 2 | 14 3 | 21 4 | 22 5 | 24 6 | 30 7 |   8 |  i0 c 9 | i1 d 10 | l0 a 11 | l1 AIGER_NOT_b 12 | b0 AIGER_NEVER_0 13 | b1 AIGER_NEVER_1 14 | c0 AIGER_INVAR_0 15 | c 16 | smvtoaig 17 | 1.9 18 | mult2.flatsmv 19 | -------------------------------------------------------------------------------- /examples/smv/latch0.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | a : boolean; 4 | b : boolean; 5 | c : boolean; 6 | ASSIGN 7 | init (a) := TRUE; 8 | init (c) := TRUE; 9 | next (a) := case c : a; TRUE : b; esac; 10 | next (c) := !c; 11 | next (b) := a; 12 | SPEC 13 | AG a 14 | -------------------------------------------------------------------------------- /testaigbmc: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | run () { 3 | echo $1 4 | ./aigbmc examples/$1 > /tmp/testaigbmc.wit 5 | grep '^[bc]' /tmp/testaigbmc.wit 6 | ./aigsim -c examples/$1 /tmp/testaigbmc.wit 7 | } 8 | 9 | run cnt1.aag 10 | run cnt1e.aag 11 | run notcnt1.aag 12 | run notcnt1e.aag 13 | -------------------------------------------------------------------------------- /log/cnt2e.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | x : boolean; 4 | y : boolean; 5 | e : boolean; 6 | ASSIGN 7 | init (x) := FALSE; 8 | next (x) := case e : !x; TRUE : x; esac; 9 | init (y) := FALSE; 10 | next (y) := case e : y <-> !x; TRUE : y; esac; 11 | SPEC 12 | AG !(x & y) 13 | -------------------------------------------------------------------------------- /log/cnt3.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | x : boolean; 4 | y : boolean; 5 | z : boolean; 6 | ASSIGN 7 | init (x) := FALSE; 8 | next (x) := !x; 9 | init (y) := FALSE; 10 | next (y) := y <-> !x; 11 | init (z) := FALSE; 12 | next (z) := z <-> !(x & y); 13 | SPEC 14 | AG !(x & y & z) 15 | -------------------------------------------------------------------------------- /log/cnt2re.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | x : boolean; 4 | y : boolean; 5 | e : boolean; 6 | r : boolean; 7 | ASSIGN 8 | init (x) := FALSE; 9 | next (x) := !r & case e : !x; TRUE : x; esac; 10 | init (y) := FALSE; 11 | next (y) := !r & case e : y <-> !x; TRUE : y; esac; 12 | SPEC 13 | AG !(x & y) 14 | -------------------------------------------------------------------------------- /log/cnt4.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR e : boolean; 3 | VAR r : boolean; 4 | VAR x : 0..4; 5 | ASSIGN init(x) := 0; 6 | ASSIGN next(x) := case r : 0; !e : x; x < 3 : x + 1; TRUE : 0; esac; 7 | SPEC AG !(x = 0) 8 | SPEC AG !(x = 1) 9 | SPEC AG !(x = 2) 10 | SPEC AG !(x = 3) 11 | SPEC AG !(x = 4) 12 | LTLSPEC F G (x < 3) 13 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | add primary inputs in delta debugger 2 | add 'B I L F' 3 | check symbol names in 'aigtoblif' und 'aigtosmv' 4 | fix problems with just having 'aig' as output file name 5 | add gzip to 'aigtocnf' 6 | add verbose options to 'aigbmc' 7 | replace the AIG library in 'smvtoaig' with SimpAIG. 8 | replace the AIG library in 'bliftoaig' with SimpAIG. 9 | -------------------------------------------------------------------------------- /examples/smv/mult2.flatsmv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | a : boolean; 4 | b : boolean; 5 | c : boolean; 6 | d : boolean; 7 | ASSIGN 8 | init(a) := FALSE; 9 | init(b) := TRUE; 10 | next(a) := (b | !c) & (a | c); 11 | next(b) := (a | !d) & (b | d); 12 | INVAR 13 | c <-> d 14 | SPEC 15 | AG (!a | !b) 16 | SPEC 17 | AG (a | b) 18 | -------------------------------------------------------------------------------- /examples/smv/latch2.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | a : boolean; 4 | b : boolean; 5 | c : boolean; 6 | d : boolean; 7 | e : boolean; 8 | f : boolean; 9 | ASSIGN 10 | init (a) := FALSE; 11 | init (b) := TRUE; 12 | init (d) := TRUE; 13 | init (e) := FALSE; 14 | next (a) := !a; 15 | next (b) := !b; 16 | next (c) := !c; 17 | SPEC 18 | AG (a | b | c | d | e | f) 19 | -------------------------------------------------------------------------------- /aiginterleave.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cat $1 | \ 3 | aigstrip | \ 4 | aigtoaig -a | \ 5 | awk ' 6 | /^aag /{ 7 | print 8 | n=$3 9 | next 10 | } 11 | { 12 | if (NR > n + 1) print; 13 | else { 14 | inputs[NR-2]=$1; 15 | if (NR == n+1) { 16 | for (i = 0; i < n/2; i++) { 17 | print inputs[i]; 18 | print inputs[n/2 + i]; 19 | } 20 | } 21 | } 22 | }'|aigtoaig - $2 23 | -------------------------------------------------------------------------------- /log/cnt3e.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | x : boolean; 4 | y : boolean; 5 | z : boolean; 6 | e : boolean; 7 | ASSIGN 8 | init (x) := FALSE; 9 | next (x) := case e : !x; TRUE : x; esac; 10 | init (y) := FALSE; 11 | next (y) := case e : y <-> !x; TRUE : y; esac; 12 | init (z) := FALSE; 13 | next (z) := case e : z <-> !(x & y); TRUE : z; esac; 14 | SPEC 15 | AG !(x & y & z) 16 | -------------------------------------------------------------------------------- /aigdeinterleave.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cat $1 | \ 3 | aigstrip | \ 4 | aigtoaig -a | \ 5 | awk ' 6 | /^aag /{ 7 | print 8 | n=$3 9 | next 10 | } 11 | { 12 | if (NR > n + 1) print; 13 | else { 14 | inputs[NR-2]=$1; 15 | if (NR == n+1) { 16 | for (i = 0; i < n/2; i++) 17 | print inputs[2*i]; 18 | for (i = 0; i < n/2; i++) 19 | print inputs[2*i + 1]; 20 | } 21 | } 22 | }'|aigtoaig - $2 23 | -------------------------------------------------------------------------------- /log/cnt3re.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | x : boolean; 4 | y : boolean; 5 | z : boolean; 6 | e : boolean; 7 | r : boolean; 8 | ASSIGN 9 | init (x) := FALSE; 10 | next (x) := !r & case e : !x; TRUE : x; esac; 11 | init (y) := FALSE; 12 | next (y) := !r & case e : y <-> !x; TRUE : y; esac; 13 | init (z) := FALSE; 14 | next (z) := !r & case e : z <-> !(x & y); TRUE : z; esac; 15 | SPEC 16 | AG !(x & y & z) 17 | -------------------------------------------------------------------------------- /examples/smv/mult2.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | a : boolean; 4 | b : boolean; 5 | c : boolean; 6 | d : boolean; 7 | ASSIGN 8 | init (a) := FALSE; 9 | init (b) := TRUE; 10 | next (a) := 11 | case 12 | c : b; 13 | TRUE : a; 14 | esac; 15 | next (b) := 16 | case 17 | d : a; 18 | TRUE : b; 19 | esac; 20 | INVAR 21 | c = d 22 | SPEC 23 | AG !(a & b) 24 | SPEC 25 | AG !(!a & !b) 26 | -------------------------------------------------------------------------------- /verify_bliftoaig: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | rm -f /tmp/tmp1.blif 3 | cat $1 > /tmp/tmp1.blif 4 | #echo "bliftoaig" 5 | ./bliftoaig $1 /tmp/tmp.aig || exit 1 6 | #echo "aigtoblif" 7 | ./aigtoblif /tmp/tmp.aig /tmp/tmp2.blif || exit 1 8 | res=`vis -x -c 'seq_verify -b /tmp/tmp1.blif /tmp/tmp2.blif'` 9 | rm -f /tmp/tmp1.blif /tmp/tmp.aig /tmp/tmp2.blif 10 | if [ X"$res" = X"Networks are sequentially equivalent." ] 11 | then 12 | : 13 | else 14 | echo $res 15 | fi 16 | -------------------------------------------------------------------------------- /aigswap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cat $1 | \ 3 | aigstrip | \ 4 | aigtoaig -a | \ 5 | awk ' 6 | /^aag /{ 7 | print 8 | n=$3 9 | if (n%2) { 10 | print "*** error odd number of inputs" 11 | exit 12 | } 13 | next 14 | } 15 | { 16 | if (NR > n + 1) print; 17 | else { 18 | inputs[NR-2]=$1; 19 | if (NR == n+1) { 20 | for (i = 0; i < n/2; i++) { 21 | print inputs[2*i + 1]; 22 | print inputs[2*i] 23 | } 24 | } 25 | } 26 | }'|aigtoaig - $2 27 | -------------------------------------------------------------------------------- /aigswap2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cat $1 | \ 3 | aigstrip | \ 4 | aigtoaig -a | \ 5 | awk ' 6 | /^aag /{ 7 | print 8 | n=$3 9 | if (n%2) { 10 | print "*** error odd number of inputs" 11 | exit 12 | } 13 | next 14 | } 15 | { 16 | if (NR > n + 1) print; 17 | else { 18 | inputs[NR-2]=$1; 19 | if (NR == n+1) { 20 | for (i = 0; i < n/2; i++) 21 | print inputs[n/2 + i]; 22 | for (i = 0; i < n/2; i++) 23 | print inputs[i]; 24 | } 25 | } 26 | }'|aigtoaig - $2 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | aigand 3 | aigbmc 4 | aigdd 5 | aigdep 6 | aigflip 7 | aigfuzz 8 | aiginfo 9 | aigjoin 10 | aigmiter 11 | aigmove 12 | aignm 13 | aigor 14 | aigreset 15 | aigselect 16 | aigsim 17 | aigsplit 18 | aigstrip 19 | aigtoaig 20 | aigtoblif 21 | aigtobtor 22 | aigtocnf 23 | aigtodot 24 | aigtosmv 25 | aiguncomment 26 | aigunconstraint 27 | aigunor 28 | aigunroll 29 | andtoaig 30 | bliftoaig 31 | cscope.out 32 | smvtoaig 33 | soltostim 34 | testaigtoaig 35 | testsimpaig 36 | wrapstim 37 | makefile 38 | -------------------------------------------------------------------------------- /testandtoaig: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | tc () { 4 | echo -n $1 5 | ./andtoaig log/$1.and log/$1.aag 2>log/$1.err 6 | touch log/$1.aag 7 | cat log/$1.aag log/$1.err > log/$1.log 8 | if diff -q log/$1.log log/$1.out 1>/dev/null 2>/dev/null 9 | then 10 | ok=`expr $ok + 1` 11 | echo " OK" 12 | else 13 | failed=`expr $failed + 1` 14 | echo " FAILED" 15 | fi 16 | } 17 | 18 | ok=0 19 | failed=0 20 | 21 | tc empty 22 | tc and1 23 | tc and2 24 | tc and3 25 | 26 | echo "$ok ok, $failed failed" 27 | -------------------------------------------------------------------------------- /log/s27.blif: -------------------------------------------------------------------------------- 1 | .model s27.bench 2 | .inputs G0 G1 G2 G3 3 | .outputs G17 4 | .wire_load_slope 0.00 5 | .latch G10 G5 0 6 | .latch G11 G6 0 7 | .latch G13 G7 0 8 | .names G11 G17 9 | 0 1 10 | .names G14 G11 G10 11 | 00 1 12 | .names G5 G9 G11 13 | 00 1 14 | .names G2 G12 G13 15 | 00 1 16 | .names G0 G14 17 | 0 1 18 | .names G14 G6 G8 19 | 11 1 20 | .names G1 G7 G12 21 | 00 1 22 | .names G12 G8 G15 23 | 1- 1 24 | -1 1 25 | .names G3 G8 G16 26 | 1- 1 27 | -1 1 28 | .names G16 G15 G9 29 | 0- 1 30 | -0 1 31 | .end 32 | -------------------------------------------------------------------------------- /test.mk: -------------------------------------------------------------------------------- 1 | all: testaigtoaig testsimpaig 2 | testaigtoaig: aiger.o testaigtoaig.o makefile 3 | $(CC) $(CFLAGS) -o $@ testaigtoaig.o aiger.o 4 | testsimpaig: simpaig.o testsimpaig.o makefile 5 | $(CC) $(CFLAGS) -o $@ testsimpaig.o simpaig.o 6 | testaigtoaig.o: testaigtoaig.c aiger.h makefile 7 | testsimpaig.o: testsimpaig.c simpaig.h makefile 8 | clean: testclean 9 | testclean: 10 | rm -f log/*.smvfromaig 11 | rm -f log/*.aig log/*.aag 12 | rm -f log/*.aig.gz log/*.aag.gz 13 | rm -f log/*.log log/*.err 14 | rm -f testaigtoaig testsimpaig 15 | .PHONY: testclean 16 | -------------------------------------------------------------------------------- /log/inittrans0det.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | a : boolean; 4 | b : boolean; 5 | c : boolean; 6 | at : boolean; 7 | bt : boolean; 8 | ct : boolean; 9 | i : boolean; 10 | v : boolean; 11 | ASSIGN 12 | init (a) := FALSE; 13 | next (a) := at; 14 | init (b) := FALSE; 15 | next (b) := bt; 16 | init (c) := FALSE; 17 | next (c) := ct; 18 | init (i) := FALSE; 19 | next (i) := TRUE; 20 | init (v) := FALSE; 21 | next (v) := 22 | (!i & ((at = ct) & (bt != ct))) | 23 | (v & ((at = bt) -> (a = b))); 24 | SPEC 25 | AG (v -> (a != b)) 26 | -------------------------------------------------------------------------------- /log/inittrans1det.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | a : boolean; 4 | b : boolean; 5 | c : boolean; 6 | at : boolean; 7 | bt : boolean; 8 | ct : boolean; 9 | i : boolean; 10 | v : boolean; 11 | ASSIGN 12 | init (a) := FALSE; 13 | next (a) := at; 14 | init (b) := FALSE; 15 | next (b) := bt; 16 | init (c) := FALSE; 17 | next (c) := ct; 18 | init (i) := FALSE; 19 | next (i) := TRUE; 20 | init (v) := FALSE; 21 | next (v) := 22 | (!i & ((at = ct) & (bt != ct))) | 23 | (v & ((a = b) -> (at = bt))); 24 | SPEC 25 | AG (v -> (a != b)) 26 | -------------------------------------------------------------------------------- /examples/smv/s2cunfair.flatsmv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | a0 : boolean; 4 | a1 : boolean; 5 | c0.run : boolean; 6 | c0.req : boolean; 7 | c1.run : boolean; 8 | c1.req : boolean; 9 | ASSIGN 10 | init(c0.req) := FALSE; 11 | next(c0.req) := !c0.req & c0.run | c0.req & (!a0 | !c0.run); 12 | init(c1.req) := FALSE; 13 | next(c1.req) := !c1.req & c1.run | c1.req & (!a1 | !c1.run); 14 | init(a0) := FALSE; 15 | next(a0) := c0.req & c0.run; 16 | init(a1) := FALSE; 17 | next(a1) := c1.req & c1.run; 18 | INVAR 19 | c0.run <-> !c1.run 20 | LTLSPEC 21 | G (!c0.req | F a0) 22 | LTLSPEC 23 | G (!c1.req | F a1) 24 | -------------------------------------------------------------------------------- /examples/smv/s2cunfair.smv: -------------------------------------------------------------------------------- 1 | -- run this through 'smvflatten|smvtoaig' 2 | MODULE client(ack) 3 | VAR 4 | run : boolean; 5 | req : boolean; 6 | ASSIGN 7 | init (req) := FALSE; 8 | next (req) := 9 | case 10 | run & !req : TRUE; 11 | run & ack : FALSE; 12 | TRUE : req; 13 | esac; 14 | LTLSPEC G (req -> F ack) 15 | MODULE main 16 | VAR 17 | a0 : boolean; 18 | a1 : boolean; 19 | c0 : client(a0); 20 | c1 : client(a1); 21 | INVAR 22 | !(c0.run & c1.run) 23 | INVAR 24 | c0.run | c1.run 25 | ASSIGN 26 | init (a0) := FALSE; 27 | next (a0) := c0.req & c0.run; 28 | init (a1) := FALSE; 29 | next (a1) := c1.req & c1.run; 30 | -------------------------------------------------------------------------------- /examples/code/read.c: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------*/ 2 | /* (C)opyright 2006, Armin Biere, Johannes Kepler University, see LICENSE */ 3 | /*------------------------------------------------------------------------*/ 4 | 5 | #include 6 | #include 7 | 8 | unsigned 9 | decode (FILE * file) 10 | { 11 | unsigned x = 0, i = 0; 12 | unsigned char ch; 13 | 14 | while ((ch = getc (file)) & 0x80) 15 | x |= (ch & 0x7f) << (7 * i++); 16 | 17 | return x | (ch << (7 * i)); 18 | } 19 | 20 | int 21 | main (void) 22 | { 23 | for (;;) 24 | printf ("%u\n", decode (stdin)); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /examples/smv/s2cfair.flatsmv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | a0 : boolean; 4 | a1 : boolean; 5 | c0.run : boolean; 6 | c0.req : boolean; 7 | c1.run : boolean; 8 | c1.req : boolean; 9 | ASSIGN 10 | init(c0.req) := FALSE; 11 | next(c0.req) := !c0.req & c0.run | c0.req & (!a0 | !c0.run); 12 | init(c1.req) := FALSE; 13 | next(c1.req) := !c1.req & c1.run | c1.req & (!a1 | !c1.run); 14 | init(a0) := FALSE; 15 | next(a0) := c0.req & c0.run; 16 | init(a1) := FALSE; 17 | next(a1) := c1.req & c1.run; 18 | INVAR 19 | c0.run <-> !c1.run 20 | FAIRNESS 21 | c0.run 22 | FAIRNESS 23 | c1.run 24 | LTLSPEC 25 | G (!c0.req | F a0) 26 | LTLSPEC 27 | G (!c1.req | F a1) 28 | -------------------------------------------------------------------------------- /examples/smv/s2cfair.smv: -------------------------------------------------------------------------------- 1 | -- run this through 'smvflatten|smvtoaig' 2 | MODULE client(ack) 3 | VAR 4 | run : boolean; 5 | req : boolean; 6 | ASSIGN 7 | init (req) := FALSE; 8 | next (req) := 9 | case 10 | run & !req : TRUE; 11 | run & ack : FALSE; 12 | TRUE : req; 13 | esac; 14 | LTLSPEC 15 | G (req -> F ack) 16 | FAIRNESS run 17 | MODULE main 18 | VAR 19 | a0 : boolean; 20 | a1 : boolean; 21 | c0 : client(a0); 22 | c1 : client(a1); 23 | INVAR 24 | !(c0.run & c1.run) 25 | INVAR 26 | c0.run | c1.run 27 | ASSIGN 28 | init (a0) := FALSE; 29 | next (a0) := c0.req & c0.run; 30 | init (a1) := FALSE; 31 | next (a1) := c1.req & c1.run; 32 | -------------------------------------------------------------------------------- /runaigmcncheck: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cleanup () { 3 | rm -f $sol 4 | } 5 | die () { 6 | echo "**** runaigmcncheck: $*" 1>&2 7 | cleanup 8 | exit 1 9 | } 10 | aig="" 11 | cmd="" 12 | while [ $# -gt 0 ] 13 | do 14 | case $1 in 15 | *.aig|*.aag|*.aig.gz|*.aag.gz) 16 | [ x"$aig" = x ] || die "multiple models $aig and $1" 17 | aig=$1 18 | [ x"$cmd" = x ] || cmd="$cmd " 19 | cmd="${cmd}$1" 20 | ;; 21 | *) 22 | [ x"$cmd" = x ] || cmd="$cmd " 23 | cmd="${cmd}$1" 24 | ;; 25 | esac 26 | shift 27 | done 28 | [ x"$aig" = x ] && die "no aiger model specified" 29 | [ x"$cmd" = x ] && die "no model checking command specified" 30 | sol=/tmp/runaigmcncheck-$$.sol 31 | trap "cleanup" 2 11 15 32 | rm -f $sol 33 | $cmd > $sol 34 | aigsim -m -w -c -2 $aig $sol 35 | res=$? 36 | cleanup 37 | exit $res 38 | -------------------------------------------------------------------------------- /examples/code/write.c: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------*/ 2 | /* (C)opyright 2006, Armin Biere, Johannes Kepler University, see LICENSE */ 3 | /*------------------------------------------------------------------------*/ 4 | 5 | #include 6 | #include 7 | 8 | void 9 | encode (FILE * file, unsigned x) 10 | { 11 | unsigned char ch; 12 | 13 | while (x & ~0x7f) 14 | { 15 | ch = (x & 0x7f) | 0x80; 16 | putc (ch, file); 17 | x >>= 7; 18 | } 19 | 20 | ch = x; 21 | putc (ch, file); 22 | } 23 | 24 | int 25 | main (void) 26 | { 27 | unsigned x; 28 | 29 | if (isatty (1)) 30 | { 31 | fprintf (stderr, "*** write: will not write to terminal\n"); 32 | return 1; 33 | } 34 | 35 | while (scanf ("%u", &x) != EOF) 36 | encode (stdout, x); 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /mkrelease.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | version=`cat VERSION` 3 | name=aiger-$version 4 | archive=/tmp/${name}.tar.gz 5 | dir=/tmp/$name 6 | rm -rf $dir 7 | mkdir $dir 8 | make -C doc/beyond1 2>/dev/null >/dev/null 9 | cp -a configure.sh makefile.in $dir 10 | cp -a VERSION README FORMAT LICENSE NEWS $dir 11 | cp -a doc/beyond1/beyond1.pdf $dir 12 | cp -a \ 13 | aigand.c aigbmc.c aigdd.c aiger.c aiger.h aigfuzz.c aigflip.c aigfuzz.h \ 14 | aigfuzzlayers.c aiginfo.c aigjoin.c aigmiter.c aigmove.c aignm.c aigor.c \ 15 | aigreset.c aigsim.c aigsplit.c aigstrip.c aigtoaig.c aigtoblif.c \ 16 | aigtobtor.c aigtocnf.c aigtodot.c aigtosmv.c aigunroll.c andtoaig.c \ 17 | bliftoaig.c simpaig.c simpaig.h smvtoaig.c soltostim.c wrapstim.c \ 18 | aigunconstraint.c aigdep.c \ 19 | $dir 20 | cp -a mc.sh aigvis $dir 21 | cp -ar examples $dir/ 22 | cd /tmp 23 | rm -f $archive 24 | tar zcf $archive $name 25 | rm -rf $dir 26 | ls -l $archive 27 | -------------------------------------------------------------------------------- /testsmvtoaig: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | tc () { 3 | echo -n $1 4 | ./smvtoaig log/$1.smv log/$1.aig || exit 1 5 | ./aigtosmv -b log/$1.aig log/$1.smvfromaig || exit 1 6 | old="`nusmv log/$1.smv 2>/dev/null|grep tion\ AG|awk '{printf $NF}'`" 7 | echo -n " $old" 8 | new="`nusmv log/$1.smvfromaig 2>/dev/null|grep tion\ AG|awk '{print $NF}'`" 9 | echo -n " $new" 10 | if [ $old = $new ] 11 | then 12 | ok=`expr $ok + 1` 13 | echo " OK" 14 | else 15 | failed=`expr $failed + 1` 16 | echo " FAILED" 17 | fi 18 | } 19 | 20 | ok=0 21 | failed=0 22 | 23 | tc inittrans0det 24 | tc inittrans0 25 | tc inittrans1det 26 | tc inittrans1 27 | tc initinvar0 28 | tc initinvar1 29 | tc nonext 30 | tc cnt1e 31 | tc cnt1re 32 | tc cnt1 33 | tc cnt2e 34 | tc cnt2re 35 | tc cnt2 36 | tc cnt3e 37 | tc cnt3re 38 | tc cnt3 39 | tc nonext 40 | tc regr0 41 | tc dp2 42 | tc dp3 43 | tc dp4 44 | tc nextnoinit 45 | 46 | echo "$ok ok, $failed failed" 47 | -------------------------------------------------------------------------------- /mkminrel.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | version=`cat VERSION` 3 | name=aiger-$version 4 | archive=/tmp/${name}.tar.xz 5 | dir=/tmp/$name 6 | if [ -d $dir ] 7 | then 8 | rm -f $dir/* 9 | else 10 | mkdir $dir 11 | fi 12 | cp -a VERSION $dir 13 | cp -a aiger.c aiger.h VERSION $dir 14 | cat >$dir/README<$dir/makefile.in<$dir/configure<&2; exit 1;; 32 | esac 33 | shift 34 | done 35 | sed -e "s,@COMPILE@,\$COMPILE," makefile.in > makefile 36 | EOF 37 | chmod 755 $dir/configure 38 | cd /tmp 39 | rm -f $archive 40 | tar cfJ $archive $name 41 | rm -rf $dir 42 | ls -l $archive 43 | -------------------------------------------------------------------------------- /runaigcnfuzz: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | die () { 3 | echo "*** runaigcnfuzz: $*" 1>&2 4 | exit 1 5 | } 6 | prg="" 7 | while [ $# -gt 0 ] 8 | do 9 | case $1 in 10 | -h) echo "usage: runaigcnfuzz ";exit 0;; 11 | -*) die "invalid command line option";; 12 | *) prg=$1;; 13 | esac 14 | shift 15 | done 16 | [ x"$prg" = x ] && die "no program specified" 17 | aig=/tmp/runaigcnfuzz-$$.aig 18 | cnf=/tmp/runaigcnfuzz-$$.cnf 19 | log=runaigcnfuzz-$$.log 20 | rm -f $log 21 | trap "rm -f $cnf;exit 1" 2 22 | i=0 23 | echo "[runaigcnfuzz] running $prg" 24 | echo "[runaigcnfuzz] logging $log" 25 | while true 26 | do 27 | rm -f $cnf $aig 28 | aigfuzz -m > $aig 29 | aigtocnf $aig > $cnf 30 | seed=`aiginfo $aig|awk '/^seed /{print $NF}'` 31 | head="`awk '/p cnf /{print $3, $4}' $cnf`" 32 | echo -n "$i $seed $head\r" 33 | i=`expr $i + 1` 34 | $prg $cnf 1>/dev/null 2>/dev/null 35 | case $? in 36 | 10|20) continue;; 37 | esac 38 | echo "[runaigcnfuzz] failing seed: $seed" 39 | echo $seed >> $log 40 | red=reduced-$seed 41 | ddcnfuzzed $seed $prg 1>/dev/null 2>/dev/null 42 | head="`awk '/p cnf /{print $3, $4}' $red`" 43 | echo "[runaigcnfuzz] $red $head" 44 | rm -f bug-$seed 45 | done 46 | -------------------------------------------------------------------------------- /shrinkaigerwitness.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static char * start, * top, * end; 5 | 6 | int main (void) { 7 | unsigned char uch; 8 | size_t i, size; 9 | int ch; 10 | NEXT: 11 | ch = getc (stdin); 12 | if (ch == EOF) return; 13 | if (ch == '0' || ch == '1') { 14 | top = buffer; 15 | while ((ch = getc (stdin)) != '\n') { 16 | if (ch == EOF) { 17 | fprintf (stderr, "*** shrinkaigerwitness: unexpected EOF\n"); 18 | exit (1); 19 | } 20 | if (ch != '0' && ch != '1') { 21 | fprintf (stderr, "*** shrinkaigerwitness: expected '0' or '1'\n"); 22 | exit (1); 23 | } 24 | if (top == end) { 25 | size_t oldsz = top - bufer, newsz = oldsz ? 2 * oldsz : 8192; 26 | start = realloc (start, newsz); 27 | top = start + oldsz; 28 | end = start + newsz; 29 | } 30 | *top++ = ch; 31 | } 32 | size = top - start; 33 | printf ("z%lld\n", size); 34 | uch = 0; 35 | for (i = 0; i < size; i++) { 36 | unsigned s = i & 7; 37 | uch |= ((unsigned char)(start[i] == '1')) << (s); 38 | if (s) continue; 39 | putc (uch, stdout); 40 | uch = 0; 41 | } 42 | if (i & 7) putc (uch, stdout); 43 | putc ('\n', stdout); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /jku.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (c) 2006 - 2011, Armin Biere, Johannes Kepler University. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | ***************************************************************************/ 22 | -------------------------------------------------------------------------------- /aigfuzz.h: -------------------------------------------------------------------------------- 1 | #ifndef aigfuzz_h_INCLUDED 2 | #define aigfuzz_h_INCLUDED 3 | /*************************************************************************** 4 | Copyright (c) 2009-2011, Armin Biere, Johannes Kepler University. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to 8 | deal in the Software without restriction, including without limitation the 9 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | sell copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 | IN THE SOFTWARE. 23 | ***************************************************************************/ 24 | 25 | #include "aiger.h" 26 | 27 | typedef struct aigfuzz_opts aigfuzz_opts; 28 | 29 | struct aigfuzz_opts 30 | { 31 | int merge; 32 | int small; 33 | int large; 34 | int combinational; 35 | int version; 36 | int functions; 37 | int safety; 38 | int liveness; 39 | int bad; 40 | int justice; 41 | int zero; 42 | }; 43 | 44 | void aigfuzz_msg (int level, const char *fmt, ...); 45 | void aigfuzz_opt (const char *fmt, ...); 46 | unsigned aigfuzz_pick (unsigned from, unsigned to); 47 | int aigfuzz_oneoutof (unsigned to); 48 | 49 | unsigned * aigfuzz_layers (aiger *, aigfuzz_opts *); 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /runaigfuzz: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | opts="" 3 | cmd="" 4 | ign=no 5 | aig=/tmp/runaigfuzz-$$.aig 6 | sol=/tmp/runaigfuzz-$$.sol 7 | die () { 8 | echo "*** runaigfuzz: $*" 1>&2 9 | exit 1 10 | } 11 | while [ $# -gt 0 ] 12 | do 13 | case "$1" in 14 | -h) 15 | cat< [ ...] 17 | 18 | -h print this command line option summary 19 | -i ignore valid output (0 10 20) and skip simulation 20 | 21 | -[acmslSLbj12] see 'aigfuzz -h' 22 | EOF 23 | exit 0 24 | ;; 25 | -i) ign=yes;; 26 | -m|-s|-c|-a|-c|-m|-s|-l|-S|-L|-b|-j|-1|-2) opts="$opts $1";; 27 | -*) die "invalid option '$1'";; 28 | *) cmd=$*; break;; 29 | esac 30 | shift 31 | done 32 | [ x"$cmd" = x ] && die "missing command" 33 | trap "rm -f $aig $sol; exit 1" 2 11 15 34 | cnt=0 35 | while true 36 | do 37 | printf "$cnt" 38 | rm -f $aig 39 | aigfuzz $opts > $aig 40 | seed="`aiginfo $aig|awk '/^seed/{print $2}'`" 41 | printf " $seed" 42 | header="`head -1 $aig`" 43 | printf " $header" 44 | bug=bug-$seed.aig 45 | red=red-$seed.aig 46 | rm -f $sol 47 | $cmd $aig > $sol 2>/dev/null 48 | res=$? 49 | printf " exit $res" 50 | case $res in 51 | 0|10|20) 52 | case $ign in 53 | yes) sim=no;; 54 | no) sim=yes;; 55 | esac 56 | ;; 57 | *) 58 | cp $aig $bug 59 | printf " $bug" 60 | aigdd $bug $red $cmd 61 | printf " $red" 62 | echo " `head -1 $red`" 63 | sim=no 64 | ;; 65 | esac 66 | if [ $sim = yes ] 67 | then 68 | aigsim -2 -w -c $aig $sol 1>/dev/null 2>/dev/null 69 | tmp=$? 70 | printf " aigsim $tmp" 71 | if [ $tmp = 1 ] 72 | then 73 | cp $aig $bug 74 | printf " $bug" 75 | aigdd $bug $red runaigmcncheck $cmd 76 | printf " $red" 77 | echo " `head -1 $red`" 78 | fi 79 | fi 80 | printf "\r" 81 | printf " " 82 | printf "\r" 83 | cnt=`expr $cnt + 1` 84 | done 85 | -------------------------------------------------------------------------------- /aiginfo.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (c) 2006-2007, Armin Biere, Johannes Kepler University. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | ***************************************************************************/ 22 | #include "aiger.h" 23 | 24 | #include 25 | #include 26 | 27 | int 28 | main (int argc, char **argv) 29 | { 30 | const char *file_name, *error; 31 | aiger *aiger; 32 | int i, res; 33 | 34 | file_name = 0; 35 | res = 0; 36 | 37 | for (i = 1; i < argc; i++) 38 | { 39 | if (!strcmp (argv[i], "-h")) 40 | { 41 | fprintf (stderr, "usage: aiginfo [-h][input]\n"); 42 | return 0; 43 | } 44 | else if (file_name) 45 | { 46 | fprintf (stderr, "*** [aiginfo] multiple files\n"); 47 | return 1; 48 | } 49 | else 50 | file_name = argv[i]; 51 | } 52 | 53 | aiger = aiger_init (); 54 | 55 | if (file_name) 56 | error = aiger_open_and_read_from_file (aiger, file_name); 57 | else 58 | error = aiger_read_from_file (aiger, stdin); 59 | 60 | if (error) 61 | { 62 | fprintf (stderr, "*** [aiginfo] %s\n", error); 63 | res = 1; 64 | } 65 | else 66 | res = (aiger_write_comments_to_file (aiger, stdout) == EOF); 67 | 68 | aiger_reset (aiger); 69 | 70 | return res; 71 | } 72 | -------------------------------------------------------------------------------- /aignm.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (c) 2006-2007, Armin Biere, Johannes Kepler University. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | ***************************************************************************/ 22 | 23 | #include "aiger.h" 24 | 25 | #include 26 | #include 27 | 28 | int 29 | main (int argc, char **argv) 30 | { 31 | const char *file_name, *error; 32 | aiger *aiger; 33 | int i, res; 34 | 35 | file_name = 0; 36 | res = 0; 37 | 38 | for (i = 1; i < argc; i++) 39 | { 40 | if (!strcmp (argv[i], "-h")) 41 | { 42 | fprintf (stderr, "usage: aignm [-h][input]\n"); 43 | return 0; 44 | } 45 | else if (file_name) 46 | { 47 | fprintf (stderr, "*** [aignm] multiple files\n"); 48 | return 1; 49 | } 50 | else 51 | file_name = argv[i]; 52 | } 53 | 54 | aiger = aiger_init (); 55 | 56 | if (file_name) 57 | error = aiger_open_and_read_from_file (aiger, file_name); 58 | else 59 | error = aiger_read_from_file (aiger, stdin); 60 | 61 | if (error) 62 | { 63 | fprintf (stderr, "*** [aignm] %s\n", error); 64 | res = 1; 65 | } 66 | else 67 | res = (aiger_write_symbols_to_file (aiger, stdout) == EOF); 68 | 69 | aiger_reset (aiger); 70 | 71 | return res; 72 | } 73 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | AIGER is a format, library and set of utilities for And-Inverter Graphs (AIGs). 2 | For up-to-date version and more information see 'http://fmv.jku.at/aiger'. 3 | 4 | To build use './configure.sh && make'. 5 | To install use 'make PREFIX=/usr/local install'. 6 | 7 | The focus is on conversion utilities and a generic reader and writer API. 8 | A simple AIG library 'SimpAIG' is also included. It is currently only 9 | used in unrolling sequential models in 'aigunroll'. 10 | 11 | documentation: 12 | 13 | README this file 14 | FORMAT detailed description of the format 15 | LICENSE license and copyright 16 | 17 | libraries: 18 | 19 | aiger.h API of AIGER library ('aiger.c') 20 | aiger.c read and write AIGs in AIGER format 21 | 22 | simpaig.h API of SimpAIG library ('simpaig.c') 23 | simpaig.c A compact and simple AIG library 24 | (independent from 'aiger.c') 25 | examples: 26 | 27 | examples/*.aig simple examples discussed in 'FORMAT' 28 | examples/*.aag (same in ASCII format) 29 | 30 | examples/read.c decoder code for binary integer repr. 31 | examples/write.c encoder code for binary integer repr. 32 | 33 | examples/poormanaigtocnf.c simple applications reading the binary format 34 | examples/JaigerToCNF.java without use of the AIGER library 35 | (prototypes for competition readers) 36 | utilities: 37 | 38 | aigand conjunction of all outputs 39 | aigbmc new bounded model checker for format 1.9.x including liveness 40 | aigdd delta debugger for AIGs in AIGER format 41 | aigdep determine inputs on which the outputs depend 42 | aigflip flip/negate all outputs 43 | aigfuzz fuzzer for AIGS in AIGER format 44 | aiginfo show comments of AIG 45 | aigjoin join AIGs over common inputs 46 | aigmiter generate miter of AIGER models 47 | aigmove treat non-primary outputs as primary outputs 48 | aignm show symbol table of AIG 49 | aigor disjunction of all outputs 50 | aigreset normalize constant reset either to 0 or 1 51 | aigsim simulate AIG from stimulus or randomly 52 | aigsplit split outputs into separate files 53 | aigstrip strip symbols and comments from AIG 54 | aigtoaig converts AIG formats (ascii, binary, stripped, compressed) 55 | aigtocnf translate combinational AIG into a CNF 56 | aigtoblif translate AIG into BLIF 57 | aigtodot visualizer for AIGs using 'dot' format 58 | aigtosmv translate sequential AIG to SMV format 59 | andtoaig translate file of AND gates into AIG 60 | aiguncomment strip comments from AIG 61 | aigunroll time frame expansion for bmc (previously called 'aigbmc') 62 | bliftoaig translate flat BLIF model into AIG 63 | mc.sh SAT based model checker for AIGER using these tools 64 | smvtoaig translate flat boolean encoded SMV model into AIG 65 | soltostim extract input vector from DIMACS solution 66 | wrapstim sequential stimulus from expanded combinational stimulus 67 | 68 | Armin Biere, JKU, Mai 2014. 69 | -------------------------------------------------------------------------------- /aigstrip.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (c) 2025, Armin Biere, University of Freiburg. 3 | Copyright (c) 2006-2011, Armin Biere, Johannes Kepler University. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to 7 | deal in the Software without restriction, including without limitation the 8 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9 | sell copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | IN THE SOFTWARE. 22 | ***************************************************************************/ 23 | 24 | #include "aiger.h" 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | int main(int argc, char **argv) { 33 | int i, res, files; 34 | 35 | files = 0; 36 | 37 | for (i = 1; i < argc; i++) { 38 | if (!strcmp(argv[i], "-h")) { 39 | fprintf(stderr, "usage: aigstrip [-h][]\n"); 40 | return 0; 41 | } else if (argv[i][0] == '-') { 42 | fprintf(stderr, "*** [aigstrip] invalid option '%s'\n", argv[i]); 43 | return 1; 44 | } else 45 | files++; 46 | } 47 | 48 | res = 0; 49 | 50 | for (i = !!files; i < argc; i++) { 51 | const char *name, *error; 52 | char *renamed; 53 | aiger *aiger; 54 | 55 | if (i && argv[i][0] == '-') 56 | continue; 57 | 58 | if (i) 59 | name = argv[i]; 60 | else { 61 | assert(!files); 62 | name = 0; 63 | } 64 | 65 | aiger = aiger_init(); 66 | if (!name) { 67 | if ((error = aiger_read_from_file(aiger, stdin))) 68 | goto PARSE_ERROR; 69 | (void)aiger_strip_symbols_and_comments(aiger); 70 | if (!aiger_write_to_file( 71 | aiger, (isatty(1) ? aiger_ascii_mode : aiger_binary_mode), 72 | stdout)) { 73 | fprintf(stderr, "*** [aigstrip] write error\n"); 74 | res = 1; 75 | } 76 | } else if ((error = aiger_open_and_read_from_file(aiger, name))) { 77 | PARSE_ERROR: 78 | fprintf(stderr, "*** [aigstrip] read error: %s\n", error); 79 | res = 1; 80 | } else { 81 | (void)aiger_strip_symbols_and_comments(aiger); 82 | renamed = malloc(strlen(name) + 2); 83 | sprintf(renamed, "%s~", name); 84 | 85 | if (rename(name, renamed)) { 86 | fprintf(stderr, "*** [aigstrip] failed to rename '%s'\n", name); 87 | res = 1; 88 | } else if (aiger_open_and_write_to_file(aiger, name)) { 89 | if (unlink(renamed)) { 90 | fprintf(stderr, "*** [aigstrip] failed to remove '%s'\n", renamed); 91 | } 92 | } else { 93 | 94 | fprintf(stderr, "*** [aigstrip] failed to write '%s'\n", name); 95 | res = 1; 96 | 97 | if (rename(renamed, name)) 98 | fprintf(stderr, "*** [aigstrip] backup in '%s'\n", renamed); 99 | else 100 | fprintf(stderr, "*** [aigstrip] original file restored\n"); 101 | } 102 | 103 | free(renamed); 104 | } 105 | 106 | aiger_reset(aiger); 107 | } 108 | 109 | return res; 110 | } 111 | -------------------------------------------------------------------------------- /aiguncomment.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (c) 2025, Armin Biere, University of Freiburg. 3 | Copyright (c) 2006-2011, Armin Biere, Johannes Kepler University. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to 7 | deal in the Software without restriction, including without limitation the 8 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9 | sell copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | IN THE SOFTWARE. 22 | ***************************************************************************/ 23 | 24 | #include "aiger.h" 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | int main(int argc, char **argv) { 33 | int i, res, files; 34 | 35 | files = 0; 36 | 37 | for (i = 1; i < argc; i++) { 38 | if (!strcmp(argv[i], "-h")) { 39 | fprintf(stderr, "usage: aigstrip [-h][]\n"); 40 | return 0; 41 | } else if (argv[i][0] == '-') { 42 | fprintf(stderr, "*** [aiguncomment] invalid option '%s'\n", argv[i]); 43 | return 1; 44 | } else 45 | files++; 46 | } 47 | 48 | res = 0; 49 | 50 | for (i = !!files; i < argc; i++) { 51 | const char *name, *error; 52 | char *renamed; 53 | aiger *aiger; 54 | 55 | if (i && argv[i][0] == '-') 56 | continue; 57 | 58 | if (i) 59 | name = argv[i]; 60 | else { 61 | assert(!files); 62 | name = 0; 63 | } 64 | 65 | aiger = aiger_init(); 66 | if (!name) { 67 | if ((error = aiger_read_from_file(aiger, stdin))) 68 | goto PARSE_ERROR; 69 | (void)aiger_strip_comments(aiger); 70 | if (!aiger_write_to_file( 71 | aiger, (isatty(1) ? aiger_ascii_mode : aiger_binary_mode), 72 | stdout)) { 73 | fprintf(stderr, "*** [aiguncomment] write error\n"); 74 | res = 1; 75 | } 76 | } else if ((error = aiger_open_and_read_from_file(aiger, name))) { 77 | PARSE_ERROR: 78 | fprintf(stderr, "*** [aiguncomment] read error: %s\n", error); 79 | res = 1; 80 | } else { 81 | (void)aiger_strip_comments(aiger); 82 | renamed = malloc(strlen(name) + 2); 83 | sprintf(renamed, "%s~", name); 84 | 85 | if (rename(name, renamed)) { 86 | fprintf(stderr, "*** [aiguncomment] failed to rename '%s'\n", name); 87 | res = 1; 88 | } else if (aiger_open_and_write_to_file(aiger, name)) { 89 | if (unlink(renamed)) { 90 | fprintf(stderr, "*** [aiguncomment] failed to remove '%s'\n", 91 | renamed); 92 | } 93 | } else { 94 | 95 | fprintf(stderr, "*** [aiguncomment] failed to write '%s'\n", name); 96 | res = 1; 97 | 98 | if (rename(renamed, name)) 99 | fprintf(stderr, "*** [aiguncomment] backup in '%s'\n", renamed); 100 | else 101 | fprintf(stderr, "*** [aiguncomment] original file restored\n"); 102 | } 103 | 104 | free(renamed); 105 | } 106 | 107 | aiger_reset(aiger); 108 | } 109 | 110 | return res; 111 | } 112 | -------------------------------------------------------------------------------- /configure.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | debug=no 3 | die () { 4 | echo "*** configure.sh: $*" 1>&2 5 | exit 1 6 | } 7 | usage () { 8 | echo "usage: [CC=compile] [CFLAGS=cflags] configure.sh [-h][-hg]" 9 | exit 0 10 | } 11 | wrn () { 12 | echo "[configure.sh] WARNING: $*" 1>& 2 13 | } 14 | msg () { 15 | echo "[configure.sh] $*" 1>& 2 16 | } 17 | while [ $# -gt 0 ] 18 | do 19 | case $1 in 20 | -h|--help) usage;; 21 | -g) debug=yes;; 22 | -static) static=yes;; 23 | *) die "invalid command line option '$1' (try '-h')";; 24 | esac 25 | shift 26 | done 27 | if [ x"$CC" = x ] 28 | then 29 | msg "using gcc as default compiler" 30 | CC=gcc 31 | else 32 | msg "using $CC as compiler" 33 | fi 34 | if [ x"$CFLAGS" = x ] 35 | then 36 | msg "using default compilation flags" 37 | case x"$CC" in 38 | xgcc*) 39 | CFLAGS="-Wall" 40 | if [ $debug = yes ] 41 | then 42 | CFLAGS="-g" 43 | else 44 | CFLAGS="-O3 -DNDEBUG" 45 | fi 46 | ;; 47 | *) 48 | if [ $debug = yes ] 49 | then 50 | CFLAGS="-g" 51 | else 52 | CFLAGS="-O -DNDEBUG" 53 | fi 54 | ;; 55 | esac 56 | if [ $static = yes ] 57 | then 58 | CFLAGS="$CFLAGS -static" 59 | fi 60 | else 61 | msg "using custom compilation flags" 62 | fi 63 | 64 | AIGBMCFLAGS="$CFLAGS" 65 | AIGDEPCFLAGS="$CFLAGS" 66 | 67 | PICOSAT=no 68 | if [ -d ../picosat ] 69 | then 70 | if [ -f ../picosat/picosat.h ] 71 | then 72 | if [ -f ../picosat/picosat.o ] 73 | then 74 | if [ -f ../picosat/VERSION ] 75 | then 76 | PICOSATVERSION="`cat ../picosat/VERSION`" 77 | if [ $PICOSATVERSION -lt 953 ] 78 | then 79 | wrn "out-dated version $PICOSATVERSION in '../picosat/' (need at least 953 for 'aigbmc')" 80 | else 81 | msg "found PicoSAT version $PICOSATVERSION in '../picosat'" 82 | AIGBMCTARGET="aigbmc" 83 | msg "using '../picosat/picosat.o' for 'aigbmc' and 'aigdep'" 84 | PICOSAT=yes 85 | AIGBMCHDEPS="../picosat/picosat.h" 86 | AIGBMCODEPS="../picosat/picosat.o" 87 | AIGBMCLIBS="../picosat/picosat.o" 88 | AIGBMCFLAGS="$AIGBMCFLAGS -DAIGER_HAVE_PICOSAT" 89 | fi 90 | else 91 | wrn "can not find '../picosat/VERSION' (missing for 'aigbmc')" 92 | fi 93 | else 94 | wrn \ 95 | "can not find '../picosat/picosat.o' object file (no 'aigbmc' target)" 96 | fi 97 | else 98 | wrn "can not find '../picosat/picosat.h' header (no 'aigbmc' target)" 99 | fi 100 | else 101 | wrn "can not find '../picosat' directory (no 'aigbmc' target)" 102 | fi 103 | 104 | LINGELING=no 105 | if [ -d ../lingeling ] 106 | then 107 | if [ -f ../lingeling/lglib.h ] 108 | then 109 | if [ -f ../lingeling/liblgl.a ] 110 | then 111 | msg "using '../lingeling/liblgl.a' for 'aigbmc' and 'aigdep'" 112 | LINGELING=yes 113 | AIGBMCHDEPS="$AIGBMCHDEPS ../lingeling/lglib.h" 114 | AIGBMCODEPS="$AIGBMCODEPS ../lingeling/liblgl.a" 115 | AIGBMCLIBS="$AIGBMCLIBS -L../lingeling -llgl -lm" 116 | AIGBMCFLAGS="$AIGBMCFLAGS -DAIGER_HAVE_LINGELING" 117 | else 118 | wrn "can not find '../lingeling/liblgl.a' library" 119 | fi 120 | else 121 | wrn "can not find '../lingeling/lglib.h' header" 122 | fi 123 | else 124 | wrn "can not find '../lingeling' directory" 125 | fi 126 | 127 | if [ $PICOSAT = yes -o $LINGELING = yes ] 128 | then 129 | AIGBMCTARGET="aigbmc" 130 | AIGDEPTARGET="aigdep" 131 | AIGDEPHDEPS="$AIGBMCHDEPS" 132 | AIGDEPCODEPS="$AIGBMCODEPS" 133 | AIGDEPLIBS="$AIGBMCLIBS" 134 | AIGDEPFLAGS="$AIGBMCFLAGS" 135 | else 136 | wrn "no proper '../lingeling' nor '../picosat' (will not build 'aigbmc' nor 'aigdep')" 137 | fi 138 | 139 | msg "compiling with: $CC $CFLAGS" 140 | rm -f makefile 141 | sed \ 142 | -e "s/@CC@/$CC/" \ 143 | -e "s/@CFLAGS@/$CFLAGS/" \ 144 | -e "s/@AIGBMCTARGET@/$AIGBMCTARGET/" \ 145 | -e "s/@AIGBMCTARGET@/$AIGBMCTARGET/" \ 146 | -e "s,@AIGBMCHDEPS@,$AIGBMCHDEPS," \ 147 | -e "s,@AIGBMCODEPS@,$AIGBMCODEPS," \ 148 | -e "s,@AIGBMCLIBS@,$AIGBMCLIBS," \ 149 | -e "s,@AIGBMCFLAGS@,$AIGBMCFLAGS," \ 150 | -e "s/@AIGDEPTARGET@/$AIGDEPTARGET/" \ 151 | -e "s/@AIGDEPTARGET@/$AIGDEPTARGET/" \ 152 | -e "s,@AIGDEPHDEPS@,$AIGDEPHDEPS," \ 153 | -e "s,@AIGDEPCODEPS@,$AIGDEPCODEPS," \ 154 | -e "s,@AIGDEPLIBS@,$AIGDEPLIBS," \ 155 | -e "s,@AIGDEPFLAGS@,$AIGDEPFLAGS," \ 156 | makefile.in > makefile 157 | -------------------------------------------------------------------------------- /mc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Overview: 4 | # 5 | # This is a simple bounded model checker using the utilities provided by the 6 | # AIGER library. It is an illustration on how these utilities can be used 7 | # and also defines the model checking competition input output requirements 8 | # by example. 9 | # 10 | # Installation: 11 | # 12 | # To install this model checker put it together with the utilities listed 13 | # below in 'aigertools' to the same directory and adapt the name of the 14 | # executable of a SAT solver below. The SAT solver should conform to the 15 | # SAT competition input and output requirements. 16 | # 17 | start=`date +%s` 18 | if [ x"$SATSOLVER" = x ] 19 | then 20 | satsolver="/home/biere/src/lingeling/lingeling" 21 | else 22 | satsolver="$SATSOLVER" 23 | fi 24 | 25 | # Todo: 26 | # 27 | # We need to add an k-induction based unbounded model checker to also 28 | # have an example for the ouput never being able to produce a one. This 29 | # should be included in 'aigunroll'. 30 | # 31 | 32 | # No changes are required below this line. 33 | # 34 | AIGER=/home/biere/src/aiger 35 | aigunroll=$AIGER/aigunroll 36 | aigtocnf=/$AIGER/aigtocnf 37 | soltostim=$AIGER/soltostim 38 | wrapstim=$AIGER/wrapstim 39 | aigertools="$aigunroll $aigtocnf $soltostim $wrapstim" 40 | 41 | msg () { 42 | if [ $verbose = yes ] 43 | then 44 | current=`date +%s` 45 | delta=`expr $current - $start` 46 | echo "[mc.sh] ($delta) $*" 1>&2 47 | fi 48 | } 49 | 50 | cleanup () { 51 | cd /tmp 52 | if [ $debug = yes ] 53 | then 54 | msg "keeping temporary files in $tmp" 55 | else 56 | msg "removing temporary files" 57 | rm -rf $tmp 58 | fi 59 | } 60 | 61 | die () { 62 | echo "*** [mc.sh] $*" 1>&2 63 | exit 1 64 | } 65 | 66 | input="" 67 | debug=no 68 | verbose=no 69 | maxk=1000 70 | 71 | while [ $# -gt 0 ] 72 | do 73 | case $1 in 74 | -v) verbose=yes;; 75 | -d) debug=yes;; 76 | -h) 77 | cat << EOF 78 | usage: mc.sh [-h][-v][-d][] 79 | -h print this command line option summary 80 | -v increase verbose level 81 | -d switch on debugging 82 | model in AIGER format 83 | EOF 84 | exit 0 85 | ;; 86 | -*) die "invalid command line option '$1'";; 87 | *) 88 | [ x"$input" = x ] || die "more than one model" 89 | [ -f "$1" ] || die "invalid file '$1'" 90 | input="$1" 91 | ;; 92 | esac 93 | shift 94 | done 95 | 96 | if [ $debug = yes ] 97 | then 98 | tmp=/tmp/mc.sh 99 | rm -rf $tmp || exit 1 100 | else 101 | tmp=/tmp/mc.sh-$$ 102 | fi 103 | 104 | trap 'cleanup' 0 1 2 3 6 9 14 15 105 | 106 | msg "setting up temporary directory '$tmp'" 107 | mkdir $tmp || exit 1 108 | mkdir $tmp/bin 109 | 110 | model=$tmp/model 111 | if [ x"$input" = x ] 112 | then 113 | msg "reading model from " 114 | cat $input > $model || exit 1 115 | else 116 | msg "copying $input" 117 | cp $input $model || exit 1 118 | fi 119 | 120 | basedir="`dirname $0`" 121 | [ x"$basedir" = x ] && die "empty argv[0]" 122 | [ x"$basedir" = x. ] && basedir="`pwd`" 123 | cd $basedir || exit 1 124 | 125 | for tool in $satsolver $aigertools 126 | do 127 | found=no 128 | if [ -f $tool ] 129 | then 130 | found=yes 131 | d="" 132 | else 133 | for d in `echo "$basedir:$PATH" | sed -e 's,:, ,g'` 134 | do 135 | [ -x $d/$tool ] || continue 136 | found=yes 137 | break 138 | done 139 | [ $found = no ] && \ 140 | die "could not find '$tool' in '$basedir' nor in PATH" 141 | ln -s $d/$tool $tmp/bin/$tool || exit 1 142 | fi 143 | msg "found '$d/$tool'" 144 | done 145 | 146 | PATH=$tmp/bin:$PATH 147 | 148 | [ $verbose = yes ] && verboseoption="-v" 149 | 150 | k=0 151 | msg "maximum bound $maxk" 152 | found=no 153 | while [ $k -le $maxk ] 154 | do 155 | expansion=$tmp/expansion.aig 156 | msg "$k expanding" 157 | $aigunroll $verboseoption $k $model $expansion || exit 1 158 | msg "$k converting" 159 | cnf=$tmp/cnf 160 | $aigtocnf $expansion $cnf || exit 1 161 | msg "$k $satsolver" 162 | solution=$tmp/solution 163 | $satsolver $cnf 1>$solution 164 | exitcode="$?" 165 | #msg "$k exit code $exitcode" 166 | case "$exitcode" in 167 | 10) found=yes; break;; 168 | 20) ;; 169 | *) die "'$satsolver' returns exit code 0 in iteration $k";; 170 | esac 171 | k=`expr $k + 1` 172 | done 173 | 174 | if [ $found = yes ] 175 | then 176 | echo 1 177 | msg "translating" 178 | estim=$tmp/expanded.stim 179 | $soltostim $expansion $solution > $estim 180 | msg "wrapping" 181 | $wrapstim $model $expansion $k $estim || exit 1 182 | else 183 | echo x 184 | fi 185 | 186 | exit 0 187 | -------------------------------------------------------------------------------- /andtoaig.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (c) 2006-2007, Armin Biere, Johannes Kepler University. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | ***************************************************************************/ 22 | 23 | #include "aiger.h" 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #define USAGE \ 31 | "usage: andtoaig [-a][-h][ src [ dst ]]\n" \ 32 | "\n" \ 33 | " -h print this command line option summary\n" \ 34 | " -a force ascii format\n" \ 35 | " dst output file in aiger format (default binary format)\n" \ 36 | " src file with definitions of AND gates (as in ASCII aiger format)\n" 37 | 38 | int 39 | main (int argc, char **argv) 40 | { 41 | const char *src, *dst, *error; 42 | unsigned lhs, rhs0, rhs1; 43 | unsigned i, close_file; 44 | aiger_and *and; 45 | int res, ascii; 46 | aiger *aiger; 47 | char *used; 48 | FILE *file; 49 | 50 | src = dst = 0; 51 | ascii = 0; 52 | 53 | for (i = 1; i < argc; i++) 54 | { 55 | if (!strcmp (argv[i], "-h")) 56 | { 57 | fprintf (stderr, USAGE); 58 | return 0; 59 | } 60 | else if (!strcmp (argv[i], "-a")) 61 | { 62 | ascii = 1; 63 | } 64 | else if (argv[i][0] == '-') 65 | { 66 | fprintf (stderr, 67 | "*** [andtoaig] invalid command line option '%s'\n", 68 | argv[i]); 69 | return 1; 70 | } 71 | else if (!src) 72 | src = argv[i]; 73 | else if (!dst) 74 | dst = argv[i]; 75 | else 76 | { 77 | fprintf (stderr, "*** [andtoaig] more than two files specified\n"); 78 | return 1; 79 | } 80 | } 81 | 82 | if (src) 83 | { 84 | file = fopen (src, "r"); 85 | if (!file) 86 | { 87 | fprintf (stderr, "*** [andtoaig] can not read '%s'\n", src); 88 | return 1; 89 | } 90 | 91 | close_file = 1; 92 | } 93 | else 94 | { 95 | file = stdin; 96 | close_file = 0; 97 | } 98 | 99 | if (ascii && dst) 100 | { 101 | fprintf (stderr, "*** [andtoaig] ascii format and 'dst' specified\n"); 102 | return 1; 103 | } 104 | 105 | if (!ascii && !dst && isatty (1)) 106 | ascii = 1; 107 | 108 | aiger = aiger_init (); 109 | 110 | while (fscanf (file, "%d %d %d\n", &lhs, &rhs0, &rhs1) == 3) 111 | aiger_add_and (aiger, lhs, rhs0, rhs1); 112 | 113 | if (close_file) 114 | fclose (file); 115 | 116 | used = calloc (aiger->maxvar + 1, 1); 117 | 118 | for (i = 0; i < aiger->num_ands; i++) 119 | { 120 | and = aiger->ands + i; 121 | used[aiger_lit2var (and->rhs0)] = 1; 122 | used[aiger_lit2var (and->rhs1)] = 1; 123 | } 124 | 125 | for (i = 2; i <= 2 * aiger->maxvar; i += 2) 126 | { 127 | and = aiger_is_and (aiger, i); 128 | 129 | if (used[aiger_lit2var (i)]) 130 | { 131 | if (!and) 132 | aiger_add_input (aiger, i, 0); 133 | } 134 | else if (and) 135 | aiger_add_output (aiger, i, 0); 136 | } 137 | 138 | free (used); 139 | 140 | error = aiger_check (aiger); 141 | if (error) 142 | { 143 | fprintf (stderr, "*** [andtoaig] %s\n", error); 144 | res = 1; 145 | } 146 | else 147 | { 148 | aiger_add_comment (aiger, "andtoaig"); 149 | aiger_add_comment (aiger, src ? src : ""); 150 | 151 | if (dst) 152 | res = !aiger_open_and_write_to_file (aiger, dst); 153 | else 154 | { 155 | aiger_mode mode = ascii ? aiger_ascii_mode : aiger_binary_mode; 156 | res = !aiger_write_to_file (aiger, mode, stdout); 157 | } 158 | 159 | if (res) 160 | { 161 | fprintf (stderr, 162 | "*** [andtoaig] writing to '%s' failed\n", 163 | dst ? dst : ""); 164 | } 165 | } 166 | 167 | aiger_reset (aiger); 168 | 169 | return res; 170 | } 171 | -------------------------------------------------------------------------------- /aigor.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (c) 2009-2011, Armin Biere, Johannes Kepler University. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | ***************************************************************************/ 22 | 23 | #include "aiger.h" 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #define USAGE \ 32 | "usage: aigor [-h][-v][ []]\n" \ 33 | "\n" \ 34 | "Disjunction of all outputs of an AIGER model.\n" 35 | 36 | static aiger * src, * dst; 37 | static int verbose = 0; 38 | 39 | static void 40 | die (const char *fmt, ...) 41 | { 42 | va_list ap; 43 | fputs ("*** [aigor] ", stderr); 44 | va_start (ap, fmt); 45 | vfprintf (stderr, fmt, ap); 46 | va_end (ap); 47 | fputc ('\n', stderr); 48 | fflush (stderr); 49 | exit (1); 50 | } 51 | 52 | static void 53 | msg (const char *fmt, ...) 54 | { 55 | va_list ap; 56 | if (!verbose) 57 | return; 58 | fputs ("[aigor] ", stderr); 59 | va_start (ap, fmt); 60 | vfprintf (stderr, fmt, ap); 61 | va_end (ap); 62 | fputc ('\n', stderr); 63 | fflush (stderr); 64 | } 65 | 66 | int 67 | main (int argc, char ** argv) 68 | { 69 | const char * input, * output, * err; 70 | unsigned j, out, tmp; 71 | char comment[80]; 72 | aiger_mode mode; 73 | aiger_and * a; 74 | int i, ok; 75 | 76 | input = output = 0; 77 | 78 | for (i = 1; i < argc; i++) 79 | { 80 | if (!strcmp (argv[i], "-h")) 81 | { 82 | printf ("%s", USAGE); 83 | exit (0); 84 | } 85 | 86 | if (!strcmp (argv[i], "-v")) 87 | verbose = 1; 88 | else if (argv[i][0] == '-') 89 | die ("invalid command line option '%s'", argv[i]); 90 | else if (output) 91 | die ("too many arguments"); 92 | else if (input) 93 | output = argv[i]; 94 | else 95 | input = argv[i]; 96 | } 97 | 98 | msg ("reading %s", input ? input : ""); 99 | src = aiger_init (); 100 | if (input) 101 | err = aiger_open_and_read_from_file (src, input); 102 | else 103 | err = aiger_read_from_file (src, stdin); 104 | 105 | if (err) 106 | die ("read error: %s", err); 107 | 108 | msg ("read MILOA %u %u %u %u %u", 109 | src->maxvar, 110 | src->num_inputs, 111 | src->num_latches, 112 | src->num_outputs, 113 | src->num_ands); 114 | 115 | dst = aiger_init (); 116 | for (j = 0; j < src->num_inputs; j++) 117 | aiger_add_input (dst, src->inputs[j].lit, src->inputs[j].name); 118 | 119 | for (j = 0; j < src->num_latches; j++) { 120 | aiger_add_latch (dst, src->latches[j].lit, 121 | src->latches[j].next, 122 | src->latches[j].name); 123 | aiger_add_reset (dst, src->latches[j].lit, 124 | src->latches[j].reset); 125 | } 126 | 127 | for (j = 0; j < src->num_ands; j++) 128 | { 129 | a = src->ands + j; 130 | aiger_add_and (dst, a->lhs, a->rhs0, a->rhs1); 131 | } 132 | 133 | if (src->num_outputs) 134 | { 135 | out = aiger_not (src->outputs[0].lit); 136 | for (j = 1; j < src->num_outputs; j++) 137 | { 138 | tmp = 2 * (dst->maxvar + 1); 139 | aiger_add_and (dst, tmp, out, aiger_not (src->outputs[j].lit)); 140 | out = tmp; 141 | } 142 | aiger_add_output (dst, aiger_not (out), "AIGER_OR"); 143 | } 144 | 145 | sprintf (comment, "aigor"); 146 | aiger_add_comment (dst, comment); 147 | sprintf (comment, "disjunction of %u original outputs", src->num_outputs); 148 | aiger_add_comment (dst, comment); 149 | 150 | aiger_reset (src); 151 | 152 | msg ("writing %s", output ? output : ""); 153 | 154 | if (output) 155 | ok = aiger_open_and_write_to_file (dst, output); 156 | else 157 | { 158 | mode = isatty (1) ? aiger_ascii_mode : aiger_binary_mode; 159 | ok = aiger_write_to_file (dst, mode, stdout); 160 | } 161 | 162 | if (!ok) 163 | die ("writing failed"); 164 | 165 | msg ("wrote MILOA %u %u %u %u %u", 166 | dst->maxvar, 167 | dst->num_inputs, 168 | dst->num_latches, 169 | dst->num_outputs, 170 | dst->num_ands); 171 | 172 | aiger_reset (dst); 173 | 174 | return 0; 175 | } 176 | -------------------------------------------------------------------------------- /aigand.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (c) 2009, Armin Biere, Johannes Kepler University. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | ***************************************************************************/ 22 | 23 | #include "aiger.h" 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #define USAGE \ 32 | "usage: aigand [-h][-v][ []]\n" \ 33 | "\n" \ 34 | "Conjunction of all outputs of an AIGER model.\n" 35 | 36 | static aiger * src, * dst; 37 | static int verbose = 0; 38 | 39 | static void 40 | die (const char *fmt, ...) 41 | { 42 | va_list ap; 43 | fputs ("*** [aigand] ", stderr); 44 | va_start (ap, fmt); 45 | vfprintf (stderr, fmt, ap); 46 | va_end (ap); 47 | fputc ('\n', stderr); 48 | fflush (stderr); 49 | exit (1); 50 | } 51 | 52 | static void 53 | msg (const char *fmt, ...) 54 | { 55 | va_list ap; 56 | if (!verbose) 57 | return; 58 | fputs ("[aigand] ", stderr); 59 | va_start (ap, fmt); 60 | vfprintf (stderr, fmt, ap); 61 | va_end (ap); 62 | fputc ('\n', stderr); 63 | fflush (stderr); 64 | } 65 | 66 | int 67 | main (int argc, char ** argv) 68 | { 69 | const char * input, * output, * err; 70 | unsigned j, out, tmp; 71 | char comment[80]; 72 | aiger_mode mode; 73 | aiger_and * a; 74 | int i, ok; 75 | 76 | input = output = 0; 77 | 78 | for (i = 1; i < argc; i++) 79 | { 80 | if (!strcmp (argv[i], "-h")) 81 | { 82 | printf ("%s", USAGE); 83 | exit (0); 84 | } 85 | 86 | if (!strcmp (argv[i], "-v")) 87 | verbose = 1; 88 | else if (argv[i][0] == '-') 89 | die ("invalid command line option '%s'", argv[i]); 90 | else if (output) 91 | die ("too many arguments"); 92 | else if (input) 93 | output = argv[i]; 94 | else 95 | input = argv[i]; 96 | } 97 | 98 | msg ("reading %s", input ? input : ""); 99 | src = aiger_init (); 100 | if (input) 101 | err = aiger_open_and_read_from_file (src, input); 102 | else 103 | err = aiger_read_from_file (src, stdin); 104 | 105 | if (err) 106 | die ("read error: %s", err); 107 | 108 | msg ("read MILOA %u %u %u %u %u", 109 | src->maxvar, 110 | src->num_inputs, 111 | src->num_latches, 112 | src->num_outputs, 113 | src->num_ands); 114 | 115 | if (src->num_bad) die ("can not handle bad state properties"); 116 | if (src->num_constraints) 117 | die ("can not handle environment state constraints"); 118 | if (src->num_justice) die ("can not handle justice properties"); 119 | if (src->num_fairness) die ("can not handle fairness constraints"); 120 | 121 | dst = aiger_init (); 122 | for (j = 0; j < src->num_inputs; j++) 123 | aiger_add_input (dst, src->inputs[j].lit, src->inputs[j].name); 124 | 125 | for (j = 0; j < src->num_latches; j++) { 126 | aiger_add_latch (dst, src->latches[j].lit, 127 | src->latches[j].next, 128 | src->latches[j].name); 129 | aiger_add_reset (dst, src->latches[j].lit, src->latches[j].reset); 130 | } 131 | 132 | for (j = 0; j < src->num_ands; j++) 133 | { 134 | a = src->ands + j; 135 | aiger_add_and (dst, a->lhs, a->rhs0, a->rhs1); 136 | } 137 | 138 | if (src->num_outputs) 139 | { 140 | out = src->outputs[0].lit; 141 | for (j = 1; j < src->num_outputs; j++) 142 | { 143 | tmp = 2 * (dst->maxvar + 1); 144 | aiger_add_and (dst, tmp, out, src->outputs[j].lit); 145 | out = tmp; 146 | } 147 | aiger_add_output (dst, out, "AIGER_AND"); 148 | } 149 | 150 | sprintf (comment, "aigand"); 151 | aiger_add_comment (dst, comment); 152 | sprintf (comment, "conjunction of %u original outputs", src->num_outputs); 153 | aiger_add_comment (dst, comment); 154 | 155 | aiger_reset (src); 156 | 157 | msg ("writing %s", output ? output : ""); 158 | 159 | if (output) 160 | ok = aiger_open_and_write_to_file (dst, output); 161 | else 162 | { 163 | mode = isatty (1) ? aiger_ascii_mode : aiger_binary_mode; 164 | ok = aiger_write_to_file (dst, mode, stdout); 165 | } 166 | 167 | if (!ok) 168 | die ("writing failed"); 169 | 170 | msg ("wrote MILOA %u %u %u %u %u", 171 | dst->maxvar, 172 | dst->num_inputs, 173 | dst->num_latches, 174 | dst->num_outputs, 175 | dst->num_ands); 176 | 177 | aiger_reset (dst); 178 | 179 | return 0; 180 | } 181 | -------------------------------------------------------------------------------- /aigflip.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (c) 2011, Armin Biere, Johannes Kepler University. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | ***************************************************************************/ 22 | 23 | #include "aiger.h" 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #define USAGE \ 32 | "usage: aigflip [-h][-v][ []]\n" \ 33 | "\n" \ 34 | "Flip (negate) all outputs of an AIGER model.\n" 35 | 36 | static aiger * src, * dst; 37 | static int verbose = 0; 38 | 39 | static void 40 | die (const char *fmt, ...) 41 | { 42 | va_list ap; 43 | fputs ("*** [aigflip] ", stderr); 44 | va_start (ap, fmt); 45 | vfprintf (stderr, fmt, ap); 46 | va_end (ap); 47 | fputc ('\n', stderr); 48 | fflush (stderr); 49 | exit (1); 50 | } 51 | 52 | static void 53 | msg (const char *fmt, ...) 54 | { 55 | va_list ap; 56 | if (!verbose) 57 | return; 58 | fputs ("[aigflip] ", stderr); 59 | va_start (ap, fmt); 60 | vfprintf (stderr, fmt, ap); 61 | va_end (ap); 62 | fputc ('\n', stderr); 63 | fflush (stderr); 64 | } 65 | 66 | int 67 | main (int argc, char ** argv) 68 | { 69 | const char * input, * output, * err, * srcname; 70 | unsigned out, tmp; 71 | char comment[80]; 72 | aiger_mode mode; 73 | char * dstname; 74 | aiger_and * a; 75 | int i, ok; 76 | 77 | input = output = 0; 78 | 79 | for (i = 1; i < argc; i++) 80 | { 81 | if (!strcmp (argv[i], "-h")) 82 | { 83 | printf ("%s", USAGE); 84 | exit (0); 85 | } 86 | 87 | if (!strcmp (argv[i], "-v")) 88 | verbose = 1; 89 | else if (argv[i][0] == '-') 90 | die ("invalid command line option '%s'", argv[i]); 91 | else if (output) 92 | die ("too many arguments"); 93 | else if (input) 94 | output = argv[i]; 95 | else 96 | input = argv[i]; 97 | } 98 | 99 | msg ("reading %s", input ? input : ""); 100 | src = aiger_init (); 101 | if (input) 102 | err = aiger_open_and_read_from_file (src, input); 103 | else 104 | err = aiger_read_from_file (src, stdin); 105 | 106 | if (err) 107 | die ("read error: %s", err); 108 | 109 | msg ("read MILOA %u %u %u %u %u", 110 | src->maxvar, 111 | src->num_inputs, 112 | src->num_latches, 113 | src->num_outputs, 114 | src->num_ands); 115 | 116 | if (src->num_bad) die ("can not handle bad state properties"); 117 | if (src->num_constraints) 118 | die ("can not handle environment state constraints"); 119 | if (src->num_justice) die ("can not handle justice properties"); 120 | if (src->num_fairness) die ("can not handle fairness constraints"); 121 | 122 | dst = aiger_init (); 123 | for (i = 0; i < src->num_inputs; i++) 124 | aiger_add_input (dst, src->inputs[i].lit, src->inputs[i].name); 125 | 126 | for (i = 0; i < src->num_latches; i++) { 127 | aiger_add_latch (dst, src->latches[i].lit, 128 | src->latches[i].next, 129 | src->latches[i].name); 130 | aiger_add_reset (dst, src->latches[i].lit, src->latches[i].reset); 131 | } 132 | 133 | for (i = 0; i < src->num_ands; i++) 134 | { 135 | a = src->ands + i; 136 | aiger_add_and (dst, a->lhs, a->rhs0, a->rhs1); 137 | } 138 | 139 | for (i = 0; i < src->num_outputs; i++) 140 | { 141 | out = src->outputs[i].lit; 142 | srcname = src->outputs[i].name; 143 | if (srcname) 144 | { 145 | dstname = malloc (strlen (srcname) + 20); 146 | sprintf (dstname, "AIGFLIP_%s", srcname); 147 | } 148 | else 149 | dstname = 0; 150 | aiger_add_output (dst, aiger_not (out), dstname); 151 | free (dstname); 152 | } 153 | 154 | sprintf (comment, "aigflip"); 155 | aiger_add_comment (dst, comment); 156 | sprintf (comment, "flipped/negated all original outputs"); 157 | aiger_add_comment (dst, comment); 158 | 159 | aiger_reset (src); 160 | 161 | msg ("writing %s", output ? output : ""); 162 | 163 | if (output) 164 | ok = aiger_open_and_write_to_file (dst, output); 165 | else 166 | { 167 | mode = isatty (1) ? aiger_ascii_mode : aiger_binary_mode; 168 | ok = aiger_write_to_file (dst, mode, stdout); 169 | } 170 | 171 | if (!ok) 172 | die ("writing failed"); 173 | 174 | msg ("wrote MILOA %u %u %u %u %u", 175 | dst->maxvar, 176 | dst->num_inputs, 177 | dst->num_latches, 178 | dst->num_outputs, 179 | dst->num_ands); 180 | 181 | aiger_reset (dst); 182 | 183 | return 0; 184 | } 185 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This file describes the license and copyright for the AIGER source code. 2 | 3 | Almost all of the source code of AIGER has so far been developed from 4 | scratch at the Johannes Kepler University. But contributions by authors of 5 | other institutions are very much welcome. The default license is an MIT 6 | style license, acknowledging the copyright of all its authors, and we would 7 | like to keep this license the default. Currently the only exception is 8 | 'bliftoaig.c' which contains parts of the CUDD library. Therefore 9 | license of 'bliftoaig.c' has to fall back to the slightly more restrictive 10 | BSD style license used in CUDD and discussed further down. 11 | 12 | More specifically, all source code of the AIGER library with the exception 13 | of the 'bliftoaig.c' utility falls under the following LICENSE. 14 | 15 | --------------------------------------------------------------------------- 16 | -- START OF DEFAULT LICENSE FOR AIGER SOURCE CODE ------------------------- 17 | --------------------------------------------------------------------------- 18 | Copyright (c) 2021-2025, Armin Biere, University of Freiburg, Germany. 19 | Copyright (c) 2006-2021, Armin Biere, Johannes Kepler University, Austria. 20 | Copyright (c) 2006, Marc Herbstritt, University of Freiburg, Germany. 21 | Copyright (c) 2006, Daniel Le Berre, Universite d'Artois, France. 22 | Copyright (c) 2011, Siert Wieringa, Alto University, Finland. 23 | Copyright (c) 2015, Aina Niemetz, Johannes Kepler University, Austria. 24 | 25 | Permission is hereby granted, free of charge, to any person obtaining a copy 26 | of this software and associated documentation files (the "Software"), to 27 | deal in the Software without restriction, including without limitation the 28 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 29 | sell copies of the Software, and to permit persons to whom the Software is 30 | furnished to do so, subject to the following conditions: 31 | 32 | The above copyright notice and this permission notice shall be included in 33 | all copies or substantial portions of the Software. 34 | 35 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 36 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 37 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 38 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 39 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 40 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 41 | IN THE SOFTWARE. 42 | --------------------------------------------------------------------------- 43 | -- END OF DEFAULT LICENSE FOR AIGER SOURCE CODE --------------------------- 44 | --------------------------------------------------------------------------- 45 | 46 | The list of authors and copyright holders listed in the default license 47 | contains all the authors and copyright holders of AIGER, individual source 48 | code files may only list the authors and copyright holders of the individual 49 | file. The LICENSE is the same and thus should allow to cover all the 50 | source except 'bliftoaig.c' by the above default license which lists all 51 | authors. 52 | 53 | The License for 'bliftoaig.c' is a BSD style license since it includes 54 | part of utilities derived from the CUDD library which uses a BSD style 55 | license. The full license for 'bliftoaig.c' is as follows: 56 | 57 | --------------------------------------------------------------------------- 58 | -- START OF LICENSE FOR 'bliftoaig.c' ------------------------------------- 59 | --------------------------------------------------------------------------- 60 | Copyright (c) 2006 Armin Biere, Johannes Kepler University, Austria. 61 | Copyright (c) 2006 Marc Herbstritt, University of Freiburg, Germany. 62 | Copyright (c) 1995-2004, Regents of the University of Colorado, USA. 63 | 64 | All rights reserved. 65 | 66 | Redistribution and use in source and binary forms, with or without 67 | modification, are permitted provided that the following conditions 68 | are met: 69 | 70 | Redistributions of source code must retain the above copyright 71 | notice, this list of conditions and the following disclaimer. 72 | 73 | Redistributions in binary form must reproduce the above copyright 74 | notice, this list of conditions and the following disclaimer in the 75 | documentation and/or other materials provided with the distribution. 76 | 77 | Neither the name of the authors, nor the names of contributors, nor the name 78 | of the copyright holders, including the name of the Johannes Kepler 79 | University, the name of the University of Freiburg, or the name of the 80 | University of Colorado may be used to endorse or promote products derived 81 | from this software without specific prior written permission. 82 | 83 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 84 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 85 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 86 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 87 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 88 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 89 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 90 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 91 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 92 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 93 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 94 | POSSIBILITY OF SUCH DAMAGE. 95 | -------------------------------------------------------------------------- 96 | -- END OF LICENSE FOR 'bliftoaig.c' -------------------------------------- 97 | -------------------------------------------------------------------------- 98 | -------------------------------------------------------------------------------- /NEWS.md: -------------------------------------------------------------------------------- 1 | ## Version 1.9.24 2 | 3 | - Support empty comments. 4 | 5 | ## Version 1.9.23 6 | 7 | - Reset functions. 8 | 9 | ## Version 1.9.22 10 | 11 | - Added option fuzzing and delta debugging. 12 | 13 | ## Version 1.9.21 14 | 15 | - Aigsim bugfix. 16 | 17 | ## Version 1.9.20 18 | 19 | - Added 'aignunor' utility to split ORs. 20 | - Added 'aignmiter -n' for keeping XORs as outputs. 21 | - Added 'aiguncomment' utility to just strip comments. 22 | - Added 'aiger_strip_comments', 'aiger_strip_symbols'. 23 | - Allowed 'aigstrip' utility to work on multiple files. 24 | - Fixed segmentation fault without seed for 'aigfuzz' on MacOS. 25 | 26 | ## Version 1.9.19 27 | 28 | - Added '.xz' reading and writing support. 29 | - Fixed ITE extraction issue. 30 | 31 | ## Version 1.9.18 32 | 33 | - Dedicated ITE detection and CNF encoding for 'aigtocnf'. 34 | 35 | ## Version 1.9.17 36 | 37 | - Dedicated XOR detection and CNF encoding for 'aigtocnf'. 38 | 39 | - Added '-r' option for 'aigselect'. 40 | 41 | - First output needs to be negated in 'aigor' 42 | (discovered by Gianpiero Cabodi in 2021). 43 | 44 | - Reset types during reencoding (discovered by Sam Bayless in 2016). 45 | 46 | ## Version 1.9.16 47 | 48 | - Only warn if there are no constraints in 'aigunconstraint'. 49 | - Added better parse error reporting for 'c ' versus 'c'. 50 | - Added better parse error context for failed literal reading. 51 | - Added '-u' option for 'aigunroll'. 52 | - Added 'aiger[de]interleave.sh' and 'aigerswap[2].sh' 53 | - Fixed 'aigtocnf' to properly respect inputs even if output is constant. 54 | - Allow 'x' for initialized latches in 'aigsim' (thanks to Norbert Manthey) 55 | - Added '--remove-outputs' to 'aigtoaig'. 56 | - Fixed 'aigflip' symbol issue (thanks to Heinz Riener). 57 | - Added '-f' option to 'aigsim' to filter lines. 58 | - Added 'aigdep' to list dependent variables (not working yet). 59 | 60 | ## Version 1.9.8 61 | 62 | - Added 'aigunconstraint' tool to remove environment constraints. 63 | - Run 'aigbmc' up to maximum bound or until all properties satisfied. 64 | - Optional 'Lingeling' back-end for 'aigbmc' (with cloning). 65 | - Using new reentrant interface for PicoSAT in 'aigbmc'. 66 | - Fixed 'aigtosmv' to produce correct 'init' statements. 67 | - Added 'aigreset' to normalize reset. 68 | - Fixed 'mc.sh' to use 'aigunroll'. 69 | - One and not initialized BLIF latches patch for 'bliftoaig' by Fabio Somenzi. 70 | 71 | ## Version 1.9.4 72 | 73 | - Improved 'aigdd' to maintain failure inducing '' file. 74 | - Added 'aigflip' (now actually also in the release package). 75 | - Some fixes to 'aigtosmv'. 76 | - Adapted 'smvtoaig', 'aigtosmv', 'aigsim', 'aigsplit' to new BCJF format. 77 | - Added 'aigmove' and 'aigmiter'. 78 | - Started new 'aigbmc'. 79 | - Renamed 'aigbmc' to 'aigunroll'. 80 | - Added new BCJF sections. 81 | - Fixed reencoding. 82 | - Added 'aigsplit', 'aigfuzz', 'aigand', 'aigor', and 'aigjoin'. 83 | - Removed memory leak for empty line comments. 84 | - Added command line options for executable in 'aigdd'. 85 | - More stable 'aigdd' to work with shell scripts as well. 86 | - Added binary read/write mode for compatability with Windows. 87 | - Optional '-p ' option to 'aigtosmv'. 88 | 89 | ## Version 20071012 90 | 91 | - Optionally include or strip symbols in visiualizers 'aigvis', 'aigtodot'. 92 | - Delta debugger 'aigdd' simplifies AND gates. 93 | - Fixed 'smvtoaig' for models with 'next' but no 'init' assignment. 94 | - Added 'aigvis' script (AIG->DOT->EPS->PDF, and then calls acrobat). 95 | - Allowed combinatorial assignments in ASSIGN section for 'smvtoaig'. 96 | - Fixed invalid error message if RHS contains '0' in the binary format. 97 | - Error in 'bliftoaig' if BLIF latches are not inizialized by '0'. 98 | - Fixed 'bliftoaig' (usage of 'aiger_not' instead of 'not_aig'). 99 | 100 | ## Version 20070427 101 | 102 | - Simulator 'aigsim' can now check correctness of a witness. 103 | - Fixed minor bug in reading correct AIGER file reported as incorrect. 104 | - Extended 'smvtoaig' to handle 'next' operators in 'DEFINE' section. 105 | 106 | ## Version 20070308 107 | 108 | - Added 'aigtodot' visualizer. 109 | - Fixed examples to be consistent with newer symbol table entry format. 110 | - Produce output symbols in 'aigtoblif' even if AIGER file is stripped. 111 | 112 | ## Version 20061129 113 | 114 | - New poor man model checker 'mc.sh' based on AIGER tools. 115 | - Added 'examples/JaigerToCNF.java' (with help from Daniel Le Berre). 116 | - Switched to MIT style license (except for 'bliftoaig'). 117 | - New 'wrapstim' to generate stimulus from time frame expanded solution. 118 | - Added stimulus and witness/counter example definitions to FORMAT report. 119 | 120 | ## Version 20061115 121 | 122 | - Made ASCII format default if output is connected to terminal. 123 | - New delta debugger for AIG tools. 124 | - New bounded model checker for AIGs. 125 | - New simple AIG library 'SimpAIG'. 126 | - Fixed various non-initialized data defects. 127 | 128 | ## Version 20061016 129 | 130 | - Added 'bliftoaig' and 'aigtoblif' by Mark Herbstritt. 131 | - Adapted LICENSE. 132 | 133 | ## Version 20061011 134 | 135 | - Fixed 'smvtoaig' for models with 'init' but no 'next' assignments. 136 | - Adapted 'andtoaig' to new API. 137 | 138 | ## Version 20061005 139 | 140 | - Beta version and second public release. 141 | 142 | - Renamed 'big' to 'aig' and 'aig' to 'aag' to reflect the fact that 143 | the old binary 'big' format is really the default format. There is no 144 | '.big' file extension any more. 145 | 146 | - Dropped second field in symbol table entries, since it was redundant. 147 | 148 | ## Version 20060915 149 | 150 | - Alpha version and first public release. 151 | -------------------------------------------------------------------------------- /makefile.in: -------------------------------------------------------------------------------- 1 | PREFIX=/usr/local/ 2 | 3 | CC=@CC@ 4 | CFLAGS=@CFLAGS@ 5 | 6 | .c.o: 7 | $(CC) $(CFLAGS) -c $< 8 | 9 | OBJS= \ 10 | aiger.o \ 11 | simpaig.o 12 | 13 | BINS= \ 14 | aigand \ 15 | aigdd \ 16 | aigflip \ 17 | aigfuzz \ 18 | aiginfo \ 19 | aigjoin \ 20 | aigmiter \ 21 | aigmove \ 22 | aignm \ 23 | aigor \ 24 | aigreset \ 25 | aigselect \ 26 | aigsim \ 27 | aigsplit \ 28 | aigstrip \ 29 | aigtoaig \ 30 | aigtoblif \ 31 | aigtocnf \ 32 | aigtobtor \ 33 | aigtodot \ 34 | aigtosmv \ 35 | aiguncomment \ 36 | aigunconstraint \ 37 | aigunor \ 38 | aigunroll \ 39 | andtoaig \ 40 | bliftoaig \ 41 | smvtoaig \ 42 | soltostim \ 43 | wrapstim \ 44 | @AIGDEPTARGET@ \ 45 | @AIGBMCTARGET@ 46 | 47 | TARGETS=$(OBJS) $(BINS) 48 | 49 | all: $(TARGETS) 50 | 51 | install: install-bins # install-objs 52 | mkdir -p $(PREFIX)/bin/ 53 | install -m 755 -s $(BINS) $(PREFIX)/bin/ 54 | 55 | install-bins: $(BINS) 56 | 57 | install-objs: 58 | @echo "*** install-objs makefile goal not finished yet" 59 | 60 | LINKDIR=$$HOME/bin 61 | 62 | link: 63 | for i in $(BINS); \ 64 | do \ 65 | rm -f $(LINKDIR)/$$i; \ 66 | ln -s `pwd`/$$i $(LINKDIR)/$$i; \ 67 | done 68 | 69 | aigand: aiger.o aigand.o makefile 70 | $(CC) $(CFLAGS) -o $@ aigand.o aiger.o 71 | aigbmc: aiger.o aigbmc.o makefile @AIGBMCODEPS@ 72 | $(CC) $(CFLAGS) -o $@ aigbmc.o aiger.o @AIGBMCLIBS@ 73 | aigdd: aiger.o aigdd.o makefile 74 | $(CC) $(CFLAGS) -o $@ aigdd.o aiger.o 75 | aigdep: aiger.o aigdep.o makefile @AIGDEPCODEPS@ 76 | $(CC) $(CFLAGS) -o $@ aigdep.o aiger.o @AIGDEPLIBS@ 77 | aigflip: aiger.o aigflip.o makefile 78 | $(CC) $(CFLAGS) -o $@ aigflip.o aiger.o 79 | aigfuzz: aiger.o aigfuzz.o aigfuzzlayers.o makefile 80 | $(CC) $(CFLAGS) -o $@ aigfuzz.o aigfuzzlayers.o aiger.o 81 | aiginfo: aiger.o aiginfo.o makefile 82 | $(CC) $(CFLAGS) -o $@ aiginfo.o aiger.o 83 | aigjoin: aiger.o aigjoin.o makefile 84 | $(CC) $(CFLAGS) -o $@ aigjoin.o aiger.o 85 | aigmiter: aiger.o aigmiter.o makefile 86 | $(CC) $(CFLAGS) -o $@ aigmiter.o aiger.o 87 | aigmove: aiger.o aigmove.o makefile 88 | $(CC) $(CFLAGS) -o $@ aigmove.o aiger.o 89 | aignm: aiger.o aignm.o makefile 90 | $(CC) $(CFLAGS) -o $@ aignm.o aiger.o 91 | aigor: aiger.o aigor.o makefile 92 | $(CC) $(CFLAGS) -o $@ aigor.o aiger.o 93 | aigreset: aiger.o aigreset.o makefile 94 | $(CC) $(CFLAGS) -o $@ aigreset.o aiger.o 95 | aigselect: aiger.o aigselect.o makefile 96 | $(CC) $(CFLAGS) -o $@ aigselect.o aiger.o 97 | aigsim: aiger.o aigsim.o makefile 98 | $(CC) $(CFLAGS) -o $@ aigsim.o aiger.o 99 | aigstrip: aiger.o aigstrip.o makefile 100 | $(CC) $(CFLAGS) -o $@ aigstrip.o aiger.o 101 | aigsplit: aiger.o aigsplit.o makefile 102 | $(CC) $(CFLAGS) -o $@ aigsplit.o aiger.o 103 | aigtoaig: aiger.o aigtoaig.o makefile 104 | $(CC) $(CFLAGS) -o $@ aigtoaig.o aiger.o 105 | aigtoblif: aiger.o aigtoblif.o makefile 106 | $(CC) $(CFLAGS) -o $@ aigtoblif.o aiger.o 107 | aigtocnf: aiger.o aigtocnf.o makefile 108 | $(CC) $(CFLAGS) -o $@ aigtocnf.o aiger.o 109 | aigtobtor: aiger.o aigtobtor.o makefile 110 | $(CC) $(CFLAGS) -o $@ aigtobtor.o aiger.o 111 | aigtodot: aiger.o aigtodot.o makefile 112 | $(CC) $(CFLAGS) -o $@ aigtodot.o aiger.o 113 | aigtosmv: aiger.o aigtosmv.o makefile 114 | $(CC) $(CFLAGS) -o $@ aigtosmv.o aiger.o 115 | andtoaig: aiger.o andtoaig.o makefile 116 | $(CC) $(CFLAGS) -o $@ andtoaig.o aiger.o 117 | aiguncomment: aiger.o aiguncomment.o makefile 118 | $(CC) $(CFLAGS) -o $@ aiguncomment.o aiger.o 119 | aigunconstraint: aiger.o aigunconstraint.o simpaig.o makefile 120 | $(CC) $(CFLAGS) -o $@ aigunconstraint.o aiger.o simpaig.o 121 | aigunor: aiger.o aigunor.o makefile 122 | $(CC) $(CFLAGS) -o $@ aigunor.o aiger.o 123 | aigunroll: aiger.o aigunroll.o simpaig.o makefile 124 | $(CC) $(CFLAGS) -o $@ aigunroll.o aiger.o simpaig.o 125 | bliftoaig: aiger.o bliftoaig.o makefile 126 | $(CC) $(CFLAGS) -o $@ bliftoaig.o aiger.o 127 | smvtoaig: aiger.o smvtoaig.o makefile 128 | $(CC) $(CFLAGS) -o $@ smvtoaig.o aiger.o 129 | soltostim: aiger.o soltostim.o makefile 130 | $(CC) $(CFLAGS) -o $@ soltostim.o aiger.o 131 | wrapstim: aiger.o wrapstim.o makefile 132 | $(CC) $(CFLAGS) -o $@ wrapstim.o aiger.o 133 | 134 | aigbmc.o: aiger.h aigbmc.c makefile @AIGBMCHDEPS@ 135 | $(CC) @AIGBMCFLAGS@ -c aigbmc.c 136 | 137 | aigdep.o: aiger.h aigdep.c makefile @AIGDEPHDEPS@ 138 | $(CC) @AIGDEPFLAGS@ -c aigdep.c 139 | 140 | aigand.o: aiger.h aigand.c makefile 141 | aigdd.o: aiger.h aigdd.c makefile 142 | aigdep.o: aiger.h aigdep.c makefile 143 | aiger.o: aiger.h aiger.c makefile 144 | aigflip.o: aiger.h aigflip.c makefile 145 | aigfuzz.o: aigfuzz.c aigfuzz.h aiger.h makefile 146 | aigfuzzlayers.o: aigfuzzlayers.c aigfuzz.h aiger.h makefile 147 | aiginfo.o: aiginfo.c aiger.h makefile 148 | aigjoin.o: aigjoin.c aiger.h makefile 149 | aigmiter.o: aigmiter.c aiger.h makefile 150 | aigmove.o: aigmove.c aiger.h makefile 151 | aignm.o: aignm.c aiger.h makefile 152 | aigor.o: aigor.c aiger.h makefile 153 | aigreset.o: aigreset.c aiger.h makefile 154 | aigselect.o: aigselect.c aiger.h makefile 155 | aigsim.o: aigsim.c aiger.h makefile 156 | aigsplit.o: aigsplit.c aiger.h makefile 157 | aigstrip.o: aigstrip.c aiger.h makefile 158 | aigtoaig.o: aigtoaig.c aiger.h makefile 159 | aigtoblif.o: aigtoblif.c aiger.h makefile 160 | aigtocnf.o: aigtocnf.c aiger.h makefile 161 | aigtobtor.o: aigtobtor.c aiger.h makefile 162 | aigtodot.o: aigtodot.c aiger.h makefile 163 | aigtosmv.o: aigtosmv.c aiger.h makefile 164 | aigunconstraint.o: aiger.h simpaig.h aigunconstraint.c makefile 165 | aigunor.o: aiger.h aigunor.c makefile 166 | aigunroll.o: aiger.h simpaig.h aigunroll.c makefile 167 | andtoaig.o: andtoaig.c aiger.h makefile 168 | bliftoaig.o: bliftoaig.c aiger.h makefile 169 | simpaig.o: simpaig.h simpaig.c makefile 170 | smvtoaig.o: smvtoaig.c aiger.h makefile 171 | soltostim.o: soltostim.c aiger.h makefile 172 | wrapstim.o: wrapstim.c aiger.h makefile 173 | 174 | clean: 175 | rm -f *.o 176 | rm -f $(TARGETS) 177 | rm -f makefile 178 | 179 | .PHONY: all clean link install install-objs install-bins 180 | -------------------------------------------------------------------------------- /log/dp2.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | save : boolean; 4 | saved : boolean; 5 | turn_a_0 : boolean; --TYPE-- 1..2 6 | fork1_o_try___to___take___left : boolean; 7 | fork1_o_try___to___take___right : boolean; 8 | fork1_o_owner_a_1 : boolean; --TYPE-- 0..2 9 | fork1_o_owner_a_0 : boolean; 10 | fork1_o_loop_a_1 : boolean; --TYPE-- 0..2 11 | fork1_o_loop_a_0 : boolean; 12 | phil1_o_fair : boolean; 13 | phil1_o_state_a_0 : boolean; --TYPE-- eat think 14 | phil1_o_loop_a_0 : boolean; --TYPE-- eat think 15 | fork2_o_try___to___take___left : boolean; 16 | fork2_o_try___to___take___right : boolean; 17 | fork2_o_owner_a_1 : boolean; --TYPE-- 0..2 18 | fork2_o_owner_a_0 : boolean; 19 | fork2_o_loop_a_1 : boolean; --TYPE-- 0..2 20 | fork2_o_loop_a_0 : boolean; 21 | phil2_o_fair : boolean; 22 | phil2_o_state_a_0 : boolean; --TYPE-- eat think 23 | phil2_o_loop_a_0 : boolean; --TYPE-- eat think 24 | live : boolean; 25 | DEFINE 26 | fork1_o_looped := saved & (fork1_o_loop_a_0 <-> fork1_o_owner_a_0) & (fork1_o_loop_a_1 <-> fork1_o_owner_a_1); 27 | phil1_o_looped := saved & (phil1_o_loop_a_0 <-> phil1_o_state_a_0); 28 | fork2_o_looped := saved & (fork2_o_loop_a_0 <-> fork2_o_owner_a_0) & (fork2_o_loop_a_1 <-> fork2_o_owner_a_1); 29 | phil2_o_looped := saved & (phil2_o_loop_a_0 <-> phil2_o_state_a_0); 30 | found := !phil1_o_state_a_0; 31 | looped := phil1_o_looped & phil2_o_looped; 32 | fair := phil1_o_fair & phil2_o_fair; 33 | _o_MACRO1 := fork1_o_owner_a_1 | fork1_o_owner_a_0; 34 | _o_MACRO0 := !phil2_o_state_a_0 | _o_MACRO1; 35 | _o_MACRO5 := fork1_o_owner_a_0 <-> turn_a_0; 36 | _o_MACRO6 := fork1_o_owner_a_1 <-> !turn_a_0; 37 | _o_MACRO4 := _o_MACRO5 | _o_MACRO6; 38 | _o_MACRO3 := phil2_o_state_a_0 | _o_MACRO4; 39 | _o_MACRO2 := !_o_MACRO0 | _o_MACRO3; 40 | _o_MACRO7 := !_o_MACRO0 | !_o_MACRO3; 41 | _o_MACRO8 := !fork1_o_try___to___take___left | !turn_a_0; 42 | _o_MACRO9 := !phil1_o_state_a_0 | _o_MACRO1; 43 | _o_MACRO11 := phil1_o_state_a_0 | _o_MACRO4; 44 | _o_MACRO10 := !_o_MACRO9 | _o_MACRO11; 45 | _o_MACRO12 := !_o_MACRO9 | !_o_MACRO11; 46 | _o_MACRO14 := !fork1_o_try___to___take___right | turn_a_0; 47 | _o_MACRO13 := !_o_MACRO8 | _o_MACRO14; 48 | _o_MACRO15 := !_o_MACRO8 | !_o_MACRO14; 49 | _o_MACRO16 := !save | saved; 50 | _o_MACRO17 := save | saved; 51 | _o_MACRO19 := fork2_o_owner_a_1 | fork2_o_owner_a_0; 52 | _o_MACRO18 := !phil1_o_state_a_0 | _o_MACRO19; 53 | _o_MACRO23 := fork2_o_owner_a_0 <-> turn_a_0; 54 | _o_MACRO24 := fork2_o_owner_a_1 <-> !turn_a_0; 55 | _o_MACRO22 := _o_MACRO23 | _o_MACRO24; 56 | _o_MACRO21 := phil1_o_state_a_0 | _o_MACRO22; 57 | _o_MACRO20 := !_o_MACRO18 | _o_MACRO21; 58 | _o_MACRO25 := !_o_MACRO18 | !_o_MACRO21; 59 | _o_MACRO26 := !fork2_o_try___to___take___left | turn_a_0; 60 | _o_MACRO27 := !phil2_o_state_a_0 | _o_MACRO19; 61 | _o_MACRO29 := phil2_o_state_a_0 | _o_MACRO22; 62 | _o_MACRO28 := !_o_MACRO27 | _o_MACRO29; 63 | _o_MACRO30 := !_o_MACRO27 | !_o_MACRO29; 64 | _o_MACRO32 := !fork2_o_try___to___take___right | !turn_a_0; 65 | _o_MACRO31 := !_o_MACRO26 | _o_MACRO32; 66 | _o_MACRO33 := !_o_MACRO26 | !_o_MACRO32; 67 | ASSIGN 68 | init(fork1_o_owner_a_1) := FALSE; 69 | init(fork1_o_owner_a_0) := FALSE; 70 | next(fork1_o_owner_a_1) := ((turn_a_0 | _o_MACRO0) & _o_MACRO2 & (fork1_o_owner_a_1 | _o_MACRO7) | _o_MACRO8) & ((turn_a_0 | _o_MACRO9) & _o_MACRO10 & (fork1_o_owner_a_1 | _o_MACRO12) | _o_MACRO13) & (fork1_o_owner_a_1 | _o_MACRO15); 71 | next(fork1_o_owner_a_0) := (_o_MACRO8 | _o_MACRO2 & (!turn_a_0 | _o_MACRO0) & (fork1_o_owner_a_0 | _o_MACRO7)) & (_o_MACRO13 | _o_MACRO10 & (!turn_a_0 | _o_MACRO9) & (fork1_o_owner_a_0 | _o_MACRO12)) & (fork1_o_owner_a_0 | _o_MACRO15); 72 | init(fork1_o_loop_a_1) := FALSE; 73 | init(fork1_o_loop_a_0) := FALSE; 74 | next(fork1_o_loop_a_1) := (fork1_o_owner_a_1 | _o_MACRO16) & (fork1_o_loop_a_1 | !_o_MACRO16); 75 | next(fork1_o_loop_a_0) := (fork1_o_owner_a_0 | _o_MACRO16) & (fork1_o_loop_a_0 | !_o_MACRO16); 76 | init(phil1_o_state_a_0) := TRUE; 77 | next(phil1_o_state_a_0) := (!phil1_o_state_a_0 | turn_a_0 | fork1_o_owner_a_1 | !fork1_o_owner_a_0 | fork2_o_owner_a_1 | !fork2_o_owner_a_0) & (phil1_o_state_a_0 | !phil1_o_state_a_0 & !turn_a_0); 78 | init(phil1_o_loop_a_0) := TRUE; 79 | next(phil1_o_loop_a_0) := (phil1_o_state_a_0 | _o_MACRO16) & (phil1_o_loop_a_0 | !_o_MACRO16); 80 | init(phil1_o_fair) := FALSE; 81 | next(phil1_o_fair) := phil1_o_fair | !turn_a_0 & _o_MACRO17; 82 | init(fork2_o_owner_a_1) := FALSE; 83 | init(fork2_o_owner_a_0) := FALSE; 84 | next(fork2_o_owner_a_1) := ((turn_a_0 | _o_MACRO18) & _o_MACRO20 & (fork2_o_owner_a_1 | _o_MACRO25) | _o_MACRO26) & ((turn_a_0 | _o_MACRO27) & _o_MACRO28 & (fork2_o_owner_a_1 | _o_MACRO30) | _o_MACRO31) & (fork2_o_owner_a_1 | _o_MACRO33); 85 | next(fork2_o_owner_a_0) := (_o_MACRO26 | _o_MACRO20 & (!turn_a_0 | _o_MACRO18) & (fork2_o_owner_a_0 | _o_MACRO25)) & (_o_MACRO31 | _o_MACRO28 & (!turn_a_0 | _o_MACRO27) & (fork2_o_owner_a_0 | _o_MACRO30)) & (fork2_o_owner_a_0 | _o_MACRO33); 86 | init(fork2_o_loop_a_1) := FALSE; 87 | init(fork2_o_loop_a_0) := FALSE; 88 | next(fork2_o_loop_a_1) := (fork2_o_owner_a_1 | _o_MACRO16) & (fork2_o_loop_a_1 | !_o_MACRO16); 89 | next(fork2_o_loop_a_0) := (fork2_o_owner_a_0 | _o_MACRO16) & (fork2_o_loop_a_0 | !_o_MACRO16); 90 | init(phil2_o_state_a_0) := TRUE; 91 | next(phil2_o_state_a_0) := (!phil2_o_state_a_0 | !turn_a_0 | !fork2_o_owner_a_1 | fork2_o_owner_a_0 | !fork1_o_owner_a_1 | fork1_o_owner_a_0) & (phil2_o_state_a_0 | !phil2_o_state_a_0 & turn_a_0); 92 | init(phil2_o_loop_a_0) := TRUE; 93 | next(phil2_o_loop_a_0) := (phil2_o_state_a_0 | _o_MACRO16) & (phil2_o_loop_a_0 | !_o_MACRO16); 94 | init(phil2_o_fair) := FALSE; 95 | next(phil2_o_fair) := phil2_o_fair | turn_a_0 & _o_MACRO17; 96 | init(saved) := FALSE; 97 | next(saved) := _o_MACRO17; 98 | init(live) := FALSE; 99 | next(live) := found | live; 100 | --INVAR 101 | -- (!fork1_o_owner_a_1 | !fork1_o_owner_a_0) & 102 | -- (!fork1_o_loop_a_1 | !fork1_o_loop_a_0) & 103 | -- (!fork2_o_owner_a_1 | !fork2_o_owner_a_0) & 104 | -- (!fork2_o_loop_a_1 | !fork2_o_loop_a_0) 105 | SPEC 106 | AG (live | !fair | !looped) 107 | -------------------------------------------------------------------------------- /testsimpaig.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (c) 2006, Armin Biere, Johannes Kepler University. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | ***************************************************************************/ 22 | 23 | #include "simpaig.h" 24 | 25 | #ifdef NDEBUG 26 | #undef NDEBUG 27 | #endif 28 | 29 | #include 30 | 31 | static size_t allocated; 32 | 33 | static void * 34 | mymalloc (void *dummy, size_t bytes) 35 | { 36 | allocated += bytes; 37 | return malloc (bytes); 38 | } 39 | 40 | static void 41 | myfree (void *dummy, void *ptr, size_t bytes) 42 | { 43 | assert (allocated >= bytes); 44 | allocated -= bytes; 45 | free (ptr); 46 | } 47 | 48 | static void 49 | initreset (void) 50 | { 51 | simpaigmgr *mgr = simpaig_init_mem (0, mymalloc, myfree); 52 | assert (!simpaig_current_nodes (mgr)); 53 | simpaig_reset (mgr); 54 | assert (!allocated); 55 | } 56 | 57 | static void 58 | xorcmp (void) 59 | { 60 | simpaig *u, *v, *a, *b, *c, *x; 61 | simpaigmgr *mgr; 62 | 63 | mgr = simpaig_init_mem (0, mymalloc, myfree); 64 | 65 | u = simpaig_var (mgr, mgr, 0); 66 | v = simpaig_var (mgr, mgr, 1); 67 | assert (u != v); 68 | 69 | x = simpaig_xor (mgr, u, v); 70 | #if 0 71 | /* Only one of the two branches is true unless we do not have heavy 72 | * simplification enabled. 73 | */ 74 | a = simpaig_and (mgr, u, simpaig_not (v)); 75 | b = simpaig_and (mgr, v, simpaig_not (u)); 76 | c = simpaig_or (mgr, a, b); 77 | assert (c == x); 78 | simpaig_dec (mgr, a); 79 | simpaig_dec (mgr, b); 80 | simpaig_dec (mgr, c); 81 | #else 82 | a = simpaig_or (mgr, u, v); 83 | b = simpaig_or (mgr, simpaig_not (u), simpaig_not (v)); 84 | c = simpaig_and (mgr, a, b); 85 | assert (c == x); 86 | simpaig_dec (mgr, a); 87 | simpaig_dec (mgr, b); 88 | simpaig_dec (mgr, c); 89 | #endif 90 | simpaig_dec (mgr, u); 91 | simpaig_dec (mgr, v); 92 | simpaig_dec (mgr, x); 93 | 94 | assert (!simpaig_current_nodes (mgr)); 95 | simpaig_reset (mgr); 96 | assert (!allocated); 97 | } 98 | 99 | static void 100 | subst (void) 101 | { 102 | simpaigmgr *mgr = simpaig_init_mem (0, mymalloc, myfree); 103 | simpaig *u, *v, *x, *a; 104 | 105 | u = simpaig_var (mgr, mgr, 0); 106 | v = simpaig_var (mgr, mgr, 1); 107 | assert (u != v); 108 | x = simpaig_xor (mgr, u, v); 109 | 110 | simpaig_assign (mgr, v, u); 111 | a = simpaig_substitute (mgr, x); 112 | assert (simpaig_isfalse (a)); 113 | simpaig_dec (mgr, a); 114 | 115 | simpaig_assign (mgr, v, simpaig_not (u)); 116 | a = simpaig_substitute (mgr, x); 117 | assert (simpaig_istrue (a)); 118 | simpaig_dec (mgr, a); 119 | 120 | simpaig_dec (mgr, u); 121 | simpaig_dec (mgr, v); 122 | simpaig_dec (mgr, x); 123 | 124 | assert (!simpaig_current_nodes (mgr)); 125 | simpaig_reset (mgr); 126 | assert (!allocated); 127 | } 128 | 129 | static void 130 | shift (void) 131 | { 132 | simpaigmgr *mgr = simpaig_init_mem (0, mymalloc, myfree); 133 | simpaig *u, *v, *w, *a, *b, *c; 134 | 135 | u = simpaig_var (mgr, "u", 0); 136 | v = simpaig_var (mgr, "v", 1); 137 | w = simpaig_var (mgr, "w", 2); 138 | assert (u != v); 139 | assert (u != w); 140 | assert (v != w); 141 | 142 | a = simpaig_ite (mgr, u, v, w); 143 | b = simpaig_shift (mgr, a, 1); 144 | c = simpaig_shift (mgr, b, -1); 145 | assert (a == c); 146 | 147 | simpaig_dec (mgr, u); 148 | simpaig_dec (mgr, v); 149 | simpaig_dec (mgr, w); 150 | 151 | simpaig_dec (mgr, a); 152 | simpaig_dec (mgr, b); 153 | simpaig_dec (mgr, c); 154 | 155 | assert (!simpaig_current_nodes (mgr)); 156 | simpaig_reset (mgr); 157 | assert (!allocated); 158 | } 159 | 160 | static void 161 | tseitin (void) 162 | { 163 | simpaigmgr *mgr = simpaig_init_mem (0, mymalloc, myfree); 164 | simpaig *u, *v, *a, *f; 165 | 166 | u = simpaig_var (mgr, "u", 0); 167 | v = simpaig_var (mgr, "v", 0); 168 | a = simpaig_and (mgr, u, v); 169 | f = simpaig_false (mgr); 170 | 171 | assert (simpaig_max_index (mgr) == 0); 172 | assert (simpaig_index (f) == 0); 173 | assert (simpaig_int_index (f) == 1); 174 | assert (simpaig_int_index (simpaig_not (f)) == -1); 175 | assert (simpaig_unsigned_index (f) == 0); 176 | assert (simpaig_unsigned_index (simpaig_not (f)) == 1); 177 | 178 | simpaig_assign_indices (mgr, f); 179 | assert (simpaig_max_index (mgr) == 0); 180 | 181 | simpaig_assign_indices (mgr, v); 182 | assert (simpaig_max_index (mgr) == 1); 183 | assert (simpaig_index (v) == 1); 184 | simpaig_assign_indices (mgr, a); 185 | assert (simpaig_max_index (mgr) == 3); 186 | assert (simpaig_index (u) == 2); 187 | assert (simpaig_index (a) == 3); 188 | 189 | simpaig_dec (mgr, a); 190 | simpaig_dec (mgr, u); 191 | simpaig_dec (mgr, v); 192 | simpaig_dec (mgr, f); 193 | 194 | simpaig_reset_indices (mgr); /* otherwise node leaks */ 195 | assert (!simpaig_current_nodes (mgr)); 196 | simpaig_reset (mgr); 197 | assert (!allocated); 198 | } 199 | 200 | int 201 | main (void) 202 | { 203 | initreset (); 204 | xorcmp (); 205 | subst (); 206 | shift (); 207 | tseitin (); 208 | 209 | return 0; 210 | } 211 | -------------------------------------------------------------------------------- /examples/code/JaigerToCNF.java: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (c) 2006, Armin Biere, Johannes Kepler University. 3 | Copyright (c) 2006, Daniel Le Berre, Universite d'Artois. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to 7 | deal in the Software without restriction, including without limitation the 8 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9 | sell copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | IN THE SOFTWARE. 22 | ***************************************************************************/ 23 | import java.io.InputStream; 24 | import java.io.FileInputStream; 25 | import java.io.PrintStream; 26 | import java.io.IOException; 27 | import java.util.zip.GZIPInputStream; 28 | 29 | 30 | public class JaigerToCNF { 31 | 32 | static final boolean debug = false; 33 | 34 | InputStream in; 35 | PrintStream out; 36 | 37 | int M, I, L, O, A; 38 | int single_output_literal; 39 | 40 | int charno; 41 | int lineno; 42 | int prev; 43 | 44 | JaigerToCNF (InputStream in, PrintStream out) { 45 | this.in = in; 46 | this.out = out; 47 | charno = 0; 48 | lineno = 0; 49 | prev = '\n'; 50 | } 51 | 52 | int next () throws IOException { 53 | int res = in.read(); 54 | if (debug) 55 | System.err.println ("JaigerToCNF.next:" + 56 | lineno + ":" + 57 | charno + ": " + res); 58 | if (res != -1) { 59 | charno++; 60 | if (prev == '\n') 61 | lineno++; 62 | } 63 | 64 | prev = res; 65 | return res; 66 | } 67 | 68 | int aigerlit2dimacslit (int l) { 69 | int res; 70 | 71 | assert (0 <= l); 72 | assert (l <= M); 73 | 74 | int sign = l & 1; 75 | int idx = l / 2; 76 | 77 | if (idx == 0) 78 | res = M + 1; 79 | else 80 | res = idx; 81 | 82 | if (sign != 0) 83 | res *= -1; 84 | 85 | return res; 86 | } 87 | 88 | void parseError (String msg) throws IOException { 89 | throw new IOException ("line " + lineno + 90 | ": character " + charno + ": " + msg); 91 | } 92 | 93 | int parseInt (char expected) throws IOException { 94 | int res, ch; 95 | ch = next (); 96 | 97 | if (ch < '0' || ch > '9') 98 | parseError ("expected digit"); 99 | res = ch - '0'; 100 | 101 | while ((ch = next ()) >= '0' && ch <= '9') 102 | res = 10 * res + (ch - '0'); 103 | 104 | if (ch != expected) 105 | parseError ("unexpected character"); 106 | 107 | return res; 108 | } 109 | 110 | void parseHeader () throws IOException { 111 | if (next () != 'a' || 112 | next () != 'i' || 113 | next () != 'g' || 114 | next () != ' ') 115 | parseError ("expected 'aig' header line"); 116 | 117 | M = parseInt (' '); 118 | I = parseInt (' '); 119 | 120 | L = parseInt (' '); 121 | if (L > 0) 122 | parseError ("can not handle AIGs with latches"); 123 | 124 | O = parseInt (' '); 125 | if (O != 1) 126 | parseError ("expected exactly one output"); 127 | 128 | A = parseInt ('\n'); 129 | 130 | if (M != I + A) 131 | parseError ("invalid header"); 132 | } 133 | 134 | void parseOutput () throws IOException { 135 | single_output_literal = parseInt ('\n'); 136 | } 137 | 138 | int safeGet () throws IOException { 139 | int ch = next (); 140 | if (ch==-1) { 141 | parseError ("unexpected EOF"); 142 | } 143 | return ch; 144 | } 145 | 146 | int decode () throws IOException { 147 | int x = 0, i = 0; 148 | int ch; 149 | 150 | while (((ch = safeGet ()) & 0x80)>0) { 151 | x |= (ch & 0x7f) << (7 * i++); 152 | } 153 | 154 | return x | (ch << (7 * i)); 155 | } 156 | 157 | void printLiteral (int aiger_literal) { 158 | out.print (aigerlit2dimacslit (aiger_literal) + " "); 159 | } 160 | 161 | void printBinaryClause (int l1, int l2) { 162 | printLiteral (l1); 163 | printLiteral (l2); 164 | out.println("0"); 165 | } 166 | 167 | void printTernaryClause (int l1, int l2, int l3) { 168 | printLiteral (l1); 169 | printLiteral (l2); 170 | printLiteral (l3); 171 | out.println("0"); 172 | } 173 | 174 | void parseAnds () throws IOException { 175 | int lhs = 2 * (I + 1); 176 | out.println ("p cnf " + (M + 1) + " " + (3 * A + 2)); 177 | for (int i = 0; i < A; i++) { 178 | int tmp = decode (); 179 | assert (tmp < lhs); 180 | int rhs0 = lhs - tmp; 181 | tmp = decode (); 182 | assert (tmp <= rhs0); 183 | int rhs1 = rhs0 - tmp; 184 | if (debug) 185 | System.err.println ("JaigerToCNF.parseAnd: " + 186 | lhs + " " + 187 | rhs0 + " " + 188 | rhs1); 189 | printBinaryClause (-lhs, rhs0); 190 | printBinaryClause (-lhs, rhs1); 191 | printTernaryClause (lhs, -rhs0, -rhs1); 192 | lhs += 2; 193 | } 194 | } 195 | 196 | void printUnaryClause (int lit) { 197 | printLiteral (lit); 198 | out.println("0"); 199 | } 200 | 201 | void printRest () { 202 | printUnaryClause (single_output_literal); 203 | printUnaryClause (2 * (M + 1) + 1); 204 | } 205 | 206 | public static void main(String[] args) throws IOException { 207 | InputStream in; 208 | if (args.length>0) { 209 | // assuming filename is given 210 | String filename = args[0]; 211 | in = new FileInputStream(filename); 212 | 213 | if (filename.endsWith(".gz")) { 214 | in = new GZIPInputStream(in); 215 | } 216 | } else { 217 | in = System.in; 218 | } 219 | JaigerToCNF reader = new JaigerToCNF (in, System.out); 220 | reader.parseHeader(); 221 | reader.parseOutput (); 222 | reader.parseAnds (); 223 | reader.printRest (); 224 | } 225 | } 226 | -------------------------------------------------------------------------------- /aigreset.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (c) 2012, Armin Biere, Johannes Kepler University, Austria. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | ***************************************************************************/ 22 | 23 | #include "aiger.h" 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #define USAGE \ 33 | "usage: aigreset [-h][-v][-i][ []]\n" \ 34 | "\n" \ 35 | " -h print command line option summary\n" \ 36 | " -0 replace one reset by zero reset (default)\n" \ 37 | " -1 replace zero reset by one reset\n" \ 38 | " -c check if there are unitialized latches\n" \ 39 | " -v increase verbosity\n" \ 40 | "\n" \ 41 | "Normalize to zero (default) or one reset.\n" 42 | 43 | static unsigned reset, normalized; 44 | static int verbose, check; 45 | static aiger * model; 46 | 47 | static void die (const char *fmt, ...) { 48 | va_list ap; 49 | fputs ("*** [aigreset] ", stderr); 50 | va_start (ap, fmt); 51 | vfprintf (stderr, fmt, ap); 52 | va_end (ap); 53 | fputc ('\n', stderr); 54 | fflush (stderr); 55 | exit (1); 56 | } 57 | 58 | static void msg (const char *fmt, ...) { 59 | va_list ap; 60 | if (!verbose) 61 | return; 62 | fputs ("[aigreset] ", stderr); 63 | va_start (ap, fmt); 64 | vfprintf (stderr, fmt, ap); 65 | va_end (ap); 66 | fputc ('\n', stderr); 67 | fflush (stderr); 68 | } 69 | 70 | 71 | static unsigned normlit (unsigned lit) { 72 | unsigned idx = aiger_strip (lit); 73 | aiger_symbol * sym = aiger_is_latch (model, idx); 74 | if (!sym) return lit; 75 | if (sym->reset == sym->lit) return lit; 76 | if (sym->reset == reset) return lit; 77 | assert (sym->reset == aiger_not (reset)); 78 | return aiger_not (lit); 79 | } 80 | 81 | static void normlitptr (unsigned * litptr) { 82 | *litptr = normlit (*litptr); 83 | } 84 | 85 | static void normalize (void) { 86 | unsigned i, j, lit; 87 | aiger_symbol * sym; 88 | if (check) { 89 | for (i = 0; i < model->num_latches; i++) { 90 | sym = model->latches + i; 91 | if (sym->reset == sym->lit) 92 | die ("latch %u literal %u uninitialized", i, sym->lit); 93 | } 94 | } 95 | for (i = 0; i < model->num_latches; i++) { 96 | sym = model->latches + i; 97 | if (sym->reset == sym->lit) continue; 98 | if (sym->reset == reset) continue; 99 | model->latches[i].next = aiger_not (normlit (model->latches[i].next)); 100 | } 101 | for (i = 0; i < model->num_outputs; i++) 102 | normlitptr (&model->outputs[i].lit); 103 | for (i = 0; i < model->num_ands; i++) 104 | normlitptr (&model->ands[i].rhs0), 105 | normlitptr (&model->ands[i].rhs1); 106 | for (i = 0; i < model->num_bad; i++) 107 | normlitptr (&model->bad[i].lit); 108 | for (i = 0; i < model->num_constraints; i++) 109 | normlitptr (&model->constraints[i].lit); 110 | for (i = 0; i < model->num_justice; i++) 111 | for (j = 0; j < model->justice[i].size; j++) 112 | normlitptr (&model->justice[i].lits[j]); 113 | for (i = 0; i < model->num_fairness; i++) 114 | normlitptr (&model->fairness[i].lit); 115 | for (i = 0; i < model->num_latches; i++) { 116 | sym = model->latches + i; 117 | if (sym->reset == sym->lit) continue; 118 | if (sym->reset == reset) continue; 119 | assert (sym->reset == aiger_not (reset)); 120 | sym->reset = reset; 121 | normalized++; 122 | } 123 | msg ("normalized %u resets of latches to %u", normalized, reset); 124 | } 125 | 126 | int main (int argc, char ** argv) { 127 | const char * input, * output, * err; 128 | aiger_and * a; 129 | unsigned j; 130 | int i, ok; 131 | 132 | reset = aiger_false; 133 | input = output = 0; 134 | 135 | for (i = 1; i < argc; i++) { 136 | if (!strcmp (argv[i], "-h")) { printf ("%s", USAGE); exit (0); } 137 | else if (!strcmp (argv[i], "-v")) verbose = 1; 138 | else if (!strcmp (argv[i], "-0")) reset = aiger_false; 139 | else if (!strcmp (argv[i], "-1")) reset = aiger_true; 140 | else if (!strcmp (argv[i], "-c")) check = 1; 141 | else if (argv[i][0] == '-') 142 | die ("invalid command line option '%s'", argv[i]); 143 | else if (output) die ("too many arguments"); 144 | else if (input) output = argv[i]; 145 | else input = argv[i]; 146 | } 147 | 148 | model = aiger_init (); 149 | if (input) { 150 | msg ("reading '%s'", input); 151 | err = aiger_open_and_read_from_file (model, input); 152 | } else { 153 | msg ("reading ''"); 154 | err = aiger_read_from_file (model, stdin); 155 | } 156 | 157 | if (err) die ("read error: %s", err); 158 | 159 | msg ("read MILOA %u %u %u %u %u BCJF %u %u %u %u", 160 | model->maxvar, 161 | model->num_inputs, 162 | model->num_latches, 163 | model->num_outputs, 164 | model->num_ands, 165 | model->num_bad, 166 | model->num_constraints, 167 | model->num_justice, 168 | model->num_fairness); 169 | 170 | normalize (); 171 | 172 | if (output) { 173 | msg ("writing '%s'", output); 174 | ok = aiger_open_and_write_to_file (model, output); 175 | } else { 176 | msg ("writing ''", output); 177 | ok = aiger_write_to_file (model, 178 | (isatty (1) ? aiger_ascii_mode : aiger_binary_mode), stdout); 179 | } 180 | if (!ok) die ("write error"); 181 | 182 | aiger_reset (model); 183 | 184 | return 0; 185 | } 186 | -------------------------------------------------------------------------------- /examples/code/poormanaigtocnf.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (c) 2006, Armin Biere, Johannes Kepler University. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | ***************************************************************************/ 22 | 23 | /* This utility 'poormanaigtocnf' is an example on how an AIG in binary 24 | * AIGER format can be read easily if a third party tool can not use the 25 | * AIGER library. It even supports files compressed with 'gzip'. Error 26 | * handling is complete but diagnostics could be more detailed. 27 | * 28 | * In principle reading can be further speed up, by for instance using 29 | * 'fread'. In our experiments this gave a factor of sometimes 5 if no 30 | * output is produced ('--read-only'). However, we want to keep this 31 | * implementation simple and clean and writing the CNF dominates the overall 32 | * run time clearly. 33 | */ 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | static unsigned M, I, L, O, A; 42 | 43 | static int read_only; 44 | 45 | static void 46 | die (const char * fmt, ...) 47 | { 48 | va_list ap; 49 | fputs ("*** poormanaigtocnf: ", stderr); 50 | va_start (ap, fmt); 51 | vfprintf (stderr, fmt, ap); 52 | va_end (ap); 53 | fputc ('\n', stderr); 54 | exit (1); 55 | } 56 | 57 | static int 58 | u2i (unsigned l) 59 | { 60 | /* We need one more literal in the CNF for TRUE. This is the first 61 | * after the original literals in the AIG file. Signs of literals in the 62 | * AIGER format are given by the LSB, while for DIMACS it is the sign. 63 | */ 64 | if (l == 0) 65 | return -(M + 1); 66 | 67 | if (l == 1) 68 | return M + 1; 69 | 70 | return ((l & 1) ? -1 : 1) * (l >> 1); 71 | } 72 | 73 | /* Print a unary clause. 74 | */ 75 | static void 76 | c1 (unsigned a) 77 | { 78 | if (!read_only) 79 | printf ("%d 0\n", u2i (a)); 80 | } 81 | 82 | /* Print a binary clause. 83 | */ 84 | static void 85 | c2 (unsigned a, unsigned b) 86 | { 87 | if (!read_only) 88 | printf ("%d %d 0\n", u2i (a), u2i (b)); 89 | } 90 | 91 | /* Print a ternary clause. 92 | */ 93 | static void 94 | c3 (unsigned a, unsigned b, unsigned c) 95 | { 96 | if (!read_only) 97 | printf ("%d %d %d 0\n", u2i (a), u2i (b), u2i (c)); 98 | } 99 | 100 | static unsigned char 101 | get (FILE * file) 102 | { 103 | int ch = getc (file); 104 | if (ch == EOF) 105 | die ("unexpected end of file"); 106 | return (unsigned char) ch; 107 | } 108 | 109 | static unsigned 110 | decode (FILE * file) 111 | { 112 | unsigned x = 0, i = 0; 113 | unsigned char ch; 114 | 115 | while ((ch = get (file)) & 0x80) 116 | x |= (ch & 0x7f) << (7 * i++); 117 | 118 | return x | (ch << (7 * i)); 119 | } 120 | 121 | int 122 | main (int argc, char ** argv) 123 | { 124 | int close_file = 0, pclose_file = 0, verbose = 0; 125 | unsigned i, l, sat, lhs, rhs0, rhs1, delta; 126 | FILE * file = 0; 127 | 128 | for (i = 1; i < argc; i++) 129 | { 130 | if (!strcmp (argv[i], "-h")) 131 | { 132 | fprintf (stderr, 133 | "usage: " 134 | "poormanaigtocnf [-h][-v][--read-only][file.aig[.gz]]\n"); 135 | exit (0); 136 | } 137 | else if (!strcmp (argv[i], "--read-only")) 138 | read_only = 1; 139 | else if (!strcmp (argv[i], "-v")) 140 | verbose = 1; 141 | else if (file) 142 | die ("more than one file specified"); 143 | else if ((l = strlen (argv[i])) > 2 && !strcmp (argv[i] + l - 3, ".gz")) 144 | { 145 | char * cmd = malloc (l + 20); 146 | sprintf (cmd, "gunzip -c %s", argv[i]); 147 | if (!(file = popen (cmd, "r"))) 148 | die ("failed to open gzipped filed '%s' for reading", argv[i]); 149 | free (cmd); 150 | pclose_file = 1; 151 | } 152 | else if (!(file = fopen (argv[i], "r"))) 153 | die ("failed to open '%s' for reading", argv[i]); 154 | else 155 | close_file = 1; 156 | } 157 | 158 | if (!file) 159 | file = stdin; 160 | 161 | if (fscanf (file, "aig %u %u %u %u %u\n", &M, &I, &L, &O, &A) != 5) 162 | die ("invalid header"); 163 | 164 | if (verbose) 165 | fprintf (stderr, "[poormanaigtocnf] aig %u %u %u %u %u\n", M, I, L, O, A); 166 | 167 | if (L) 168 | die ("can not handle sequential models"); 169 | 170 | if (O != 1) 171 | die ("expected exactly one output"); 172 | 173 | if (fscanf (file, "%u", &sat) != 1) 174 | die ("failed to read single output literal"); 175 | 176 | /* NOTE: do not put the '\n' in the 'fscanf' format string above, since it 177 | * results in skipping additional white space if by chance the first 178 | * binary character is actually a white space character. 179 | */ 180 | if (getc (file) != '\n') 181 | die ("no new line after output"); 182 | 183 | if (!read_only) 184 | printf ("p cnf %u %u\n", M + 1, A * 3 + 2); 185 | 186 | for (lhs = 2 * (I + L + 1); A--; lhs += 2) 187 | { 188 | delta = decode (file); 189 | if (delta >= lhs) 190 | die ("invalid byte encoding of 1st RHS of %u", lhs); 191 | rhs0 = lhs - delta; 192 | 193 | delta = decode (file); 194 | if (delta > rhs0) 195 | die ("invalid byte encoding of 2nd RHS of %u", lhs); 196 | rhs1 = rhs0 - delta; 197 | 198 | c2 (lhs^1, rhs0); 199 | c2 (lhs^1, rhs1); 200 | c3 (lhs, rhs0^1, rhs1^1); 201 | } 202 | 203 | assert (lhs == 2 * (M + 1)); 204 | 205 | c1 (lhs); /* true */ 206 | c1 (sat); /* output */ 207 | 208 | if (close_file) 209 | fclose (file); 210 | 211 | if (pclose_file) 212 | pclose (file); 213 | 214 | return 0; 215 | } 216 | -------------------------------------------------------------------------------- /simpaig.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (c) 2006-2018, Armin Biere, Johannes Kepler University. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | ***************************************************************************/ 22 | 23 | /*------------------------------------------------------------------------*/ 24 | /* This file contains the API of the 'SimpAIG' library, which is a simple 25 | * implementation of an AIG data structure. The code of the library 26 | * consists of 'simpaig.c' and 'simpaig.h' and is independent of the 'AIGER' 27 | * library. 28 | */ 29 | #ifndef simpaig_h_INCLUDED 30 | #define simpaig_h_INCLUDED 31 | 32 | #include /* for 'size_t' */ 33 | 34 | typedef struct simpaigmgr simpaigmgr; 35 | typedef struct simpaig simpaig; 36 | 37 | typedef void *(*simpaig_malloc) (void *mem_mgr, size_t); 38 | typedef void (*simpaig_free) (void *mem_mgr, void *ptr, size_t); 39 | 40 | simpaigmgr *simpaig_init (void); 41 | simpaigmgr *simpaig_init_mem (void *mem_mgr, simpaig_malloc, simpaig_free); 42 | void simpaig_reset (simpaigmgr *); 43 | 44 | int simpaig_isfalse (const simpaig *); 45 | int simpaig_istrue (const simpaig *); 46 | int simpaig_signed (const simpaig *); 47 | void *simpaig_isvar (const simpaig *); 48 | int simpaig_slice (const simpaig *); 49 | int simpaig_isand (const simpaig *); 50 | 51 | /* The following functions do not give back a new reference. The reference 52 | * is shared with the argument. 53 | */ 54 | simpaig *simpaig_strip (simpaig *); 55 | simpaig *simpaig_not (simpaig *); 56 | simpaig *simpaig_child (simpaig *, int child); 57 | 58 | /* The functions below this point will all return a new reference, if they 59 | * return a 'simpaig *'. The user should delete the returned aig with 60 | * 'simpaig_dec', if memory is scarce. 61 | */ 62 | simpaig *simpaig_false (simpaigmgr *); 63 | simpaig *simpaig_true (simpaigmgr *); 64 | 65 | /* A variable in 'SimpAIG' consists of an arbitrary external pointer and a 66 | * time offset the time 'slice'. This is useful for time frame expansion. 67 | * If only combinational problems are modelled, then slice should be set 0. 68 | */ 69 | simpaig *simpaig_var (simpaigmgr *, void *var, int slice); 70 | 71 | simpaig *simpaig_and (simpaigmgr *, simpaig * a, simpaig * b); 72 | simpaig *simpaig_or (simpaigmgr *, simpaig * a, simpaig * b); 73 | simpaig *simpaig_implies (simpaigmgr *, simpaig * a, simpaig * b); 74 | simpaig *simpaig_xor (simpaigmgr *, simpaig * a, simpaig * b); 75 | simpaig *simpaig_xnor (simpaigmgr *, simpaig * a, simpaig * b); 76 | simpaig *simpaig_ite (simpaigmgr *, simpaig * c, simpaig * t, simpaig * e); 77 | 78 | /* Increment and decrement reference counts. 79 | */ 80 | simpaig *simpaig_inc (simpaigmgr *, simpaig *); 81 | void simpaig_dec (simpaigmgr *, simpaig *); 82 | 83 | /* With 'simpaig_substitute' a set of variables ('lhs') is replaced 84 | * recursively by AIGs ('rhs'). The mapping of left hand sides to right 85 | * hand sides is given by multiple calls to 'simpaig_assign' before calling 86 | * 'simpaig_substitute'. The substitution is performed recursively in such 87 | * a way that all left hand sides are eliminated. Therefore the 88 | * assignments have to be acyclic. When 'simpaig_substitute' returns the 89 | * assignment is reset. 90 | */ 91 | void simpaig_assign (simpaigmgr *, simpaig * lhs, simpaig * rhs); 92 | simpaig *simpaig_substitute (simpaigmgr *, simpaig *); 93 | 94 | /* Replace (in place) all the AIGs in the array 'a' of size 'n' recursively 95 | * and in parallel. The reference counts of the given AIGs are decremented 96 | * and thos of the resulting ones after substitution are incremented. 97 | */ 98 | void simpaig_substitute_parallel (simpaigmgr *, simpaig ** a, unsigned n); 99 | 100 | /* Shift the time by 'delta' which in essence replaces every variable by a 101 | * time shifted copy. 102 | */ 103 | simpaig *simpaig_shift (simpaigmgr *, simpaig *, int delta); 104 | 105 | /* This function will recursively assign tseitin indices to all nodes and 106 | * variables of the AIG. The return value is the maximum tseitin index 107 | * allocated, starting with 0 for the FALSE node. Tseitin indices are 108 | * shared across multiple calls to 'simpaig_assign_indices' as long 109 | * 'simpaig_reset_indices' is not called. This also means that references 110 | * to this nodes which are indexed have to be maintained. So it is always 111 | * a good idea to reset the indices after they are not used anymore. 112 | */ 113 | void simpaig_assign_indices (simpaigmgr *, simpaig *); 114 | void simpaig_reset_indices (simpaigmgr *); 115 | 116 | /* Return the 'unsigned' tseitin index of an unsigned AIG and the maximal 117 | * valid tseitin index respectively. 118 | */ 119 | unsigned simpaig_index (simpaig *); 120 | unsigned simpaig_max_index (simpaigmgr *); 121 | 122 | /* There are two ways to obtain signed tseitin indices. In the first 123 | * version we use signed numbers. A negative number denotes a negated node. 124 | * This is is how literals are defined in the DIMACS format. Note that the 125 | * absolute value of the result is the unsigned tseitin index returned by 126 | * 'simpaig_index' plus one. All indices are different from zero. 127 | * Otherwise it would be problematic to distinguish FALSE from TRUE. FALSE 128 | * has '1' as int index and TRUE '-1'. 129 | */ 130 | int simpaig_int_index (simpaig *); 131 | 132 | /* The second type of signed tseitin indices uses the least significant to 133 | * store the sign as in the AIGER format. FALSE has '0' as unsigned index 134 | * and TRUE '1'. 135 | */ 136 | unsigned simpaig_unsigned_index (simpaig *); 137 | 138 | /* The number of nodes still alive. 139 | */ 140 | unsigned simpaig_current_nodes (simpaigmgr *); 141 | 142 | #endif 143 | -------------------------------------------------------------------------------- /aigtobtor.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (c) 2006-2011, Armin Biere, Johannes Kepler University. 3 | Copyright (c) 2015 Aina Niemetz, Johannes Kepler University. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to 7 | deal in the Software without restriction, including without limitation the 8 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9 | sell copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | IN THE SOFTWARE. 22 | ***************************************************************************/ 23 | 24 | #include "aiger.h" 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | static int verbose; 33 | 34 | static void 35 | msg (const char *fmt, ...) 36 | { 37 | va_list ap; 38 | if (!verbose) return; 39 | fputs ("[aigtobtor] ", stderr); 40 | va_start (ap, fmt); 41 | vfprintf (stderr, fmt, ap); 42 | va_end (ap); 43 | fputc ('\n', stderr); 44 | fflush (stderr); 45 | } 46 | 47 | static void 48 | wrn (const char *fmt, ...) 49 | { 50 | va_list ap; 51 | fflush (stdout); 52 | fputs ("[aigtobtor] WARNING ", stderr); 53 | va_start (ap, fmt); 54 | vfprintf (stderr, fmt, ap); 55 | va_end (ap); 56 | fputc ('\n', stderr); 57 | fflush (stderr); 58 | } 59 | 60 | static void 61 | die (const char *fmt, ...) 62 | { 63 | va_list ap; 64 | fflush (stdout); 65 | fputs ("*** [aigtobtor] ", stderr); 66 | va_start (ap, fmt); 67 | vfprintf (stderr, fmt, ap); 68 | va_end (ap); 69 | fputc ('\n', stderr); 70 | exit (1); 71 | } 72 | 73 | int 74 | main (int argc, char **argv) 75 | { 76 | int i, j, lit, btorid, btorid0, btorid1, res, close_file, *map, prtmap, reft; 77 | const char *input_name, *output_name, *error; 78 | aiger *aiger; 79 | FILE *file; 80 | 81 | prtmap = 0; reft = 0; 82 | res = close_file = 0; 83 | output_name = input_name = 0; 84 | 85 | for (i = 1; i < argc; i++) 86 | { 87 | if (!strcmp (argv[i], "-h")) 88 | { 89 | fprintf (stderr, "usage: " 90 | "aigtobtor [-h][-v][-m][ []]\n"); 91 | exit (0); 92 | } 93 | else if (!strcmp (argv[i], "-m")) prtmap = 1; 94 | else if (!strcmp (argv[i], "-v")) verbose++; 95 | else if (argv[i][0] == '-') 96 | die ("invalid command line option '%s'", argv[i]); 97 | else if (!input_name) input_name = argv[i]; 98 | else if (!output_name) output_name = argv[i]; 99 | else die ("more than two files specified"); 100 | } 101 | 102 | aiger = aiger_init (); 103 | 104 | if (input_name) 105 | error = aiger_open_and_read_from_file (aiger, input_name); 106 | else 107 | error = aiger_read_from_file (aiger, stdin); 108 | 109 | if (error) 110 | die ("%s: %s", input_name ? input_name : "", error); 111 | 112 | msg ("read MILOA %u %u %u %u %u", 113 | aiger->maxvar, 114 | aiger->num_inputs, 115 | aiger->num_latches, 116 | aiger->num_outputs, 117 | aiger->num_ands); 118 | 119 | if (aiger->num_latches) die ("can not handle latches"); 120 | if (aiger->num_bad) 121 | die ("can not handle bad state properties (use 'aigmove')"); 122 | if (aiger->num_constraints) 123 | die ("can not handle environment constraints (use 'aigmove')"); 124 | if (!aiger->num_outputs) die ("no output"); 125 | if (aiger->num_justice) wrn ("ignoring justice properties"); 126 | if (aiger->num_fairness) wrn ("ignoring fairness constraints"); 127 | 128 | close_file = 0; 129 | if (output_name) 130 | { 131 | file = fopen (output_name, "w"); 132 | if (!file) die ("failed to write '%s'", output_name); 133 | close_file = 1; 134 | } 135 | else 136 | file = stdout; 137 | 138 | aiger_reencode (aiger); 139 | 140 | map = calloc (2*(aiger->maxvar+1), sizeof *map); 141 | map[0] = 1; map[1] = -1; j = 2; 142 | for (i = 0; i < aiger->num_inputs; i++) 143 | { 144 | lit = aiger->inputs[i].lit; 145 | assert (lit > 1); 146 | assert (map[lit] == 0); 147 | assert (map[aiger_not (lit)] == 0); 148 | assert (j <= aiger->maxvar+1); 149 | map[lit] = j; 150 | map[aiger_not (lit)] = -j; 151 | if (prtmap) 152 | fprintf (file, "; %d -> %d\n", lit, j); 153 | j += 1; 154 | } 155 | for (i = 0; i < aiger->num_ands; i++) 156 | { 157 | lit = aiger->ands[i].lhs; 158 | assert (map[lit] == 0); 159 | assert (map[aiger_not (lit)] == 0); 160 | assert (j <= aiger->maxvar+1); 161 | map[lit] = lit & 1 ? -j : j; 162 | map[aiger_not (lit)] = -map[lit]; 163 | if (lit == aiger_true || lit == aiger_false) reft += 1; 164 | if (prtmap) 165 | fprintf (file, "; %d -> %d\n", lit & 1 ? aiger_not (lit) : lit, j); 166 | j += 1; 167 | } 168 | for (i = 0; i < aiger->num_outputs; i++) 169 | { 170 | lit = aiger->outputs[i].lit; 171 | if (lit == aiger_true || lit == aiger_false) reft += 1; 172 | } 173 | 174 | if ((reft = reft || aiger->outputs[0].lit == 0 || aiger->outputs[0].lit == 1)) 175 | fprintf (file, "1 zero 1\n"); 176 | for (i = 0; i < aiger->num_inputs; i++) 177 | { 178 | lit = aiger->inputs[i].lit; 179 | btorid = reft ? map[lit] : map[lit]-1; 180 | fprintf (file, "%d var 1\n", btorid); 181 | } 182 | for (i = 0; i < aiger->num_ands; i++) 183 | { 184 | lit = aiger->ands[i].lhs; 185 | lit = lit & 1 ? aiger_not (lit) : lit; 186 | btorid = reft ? map[lit] : map[lit]-1; 187 | btorid0 = map[aiger->ands[i].rhs0]; 188 | btorid0 = reft ? btorid0 : (btorid0 < 0 ? btorid0+1 : btorid0-1); 189 | btorid1 = map[aiger->ands[i].rhs1]; 190 | btorid1 = reft ? btorid1 : (btorid1 < 0 ? btorid1+1 : btorid1-1); 191 | fprintf (file, "%d and 1 %d %d\n", btorid, btorid0, btorid1); 192 | } 193 | for (i = 0; i < aiger->num_outputs; i++) 194 | { 195 | lit = aiger->outputs[i].lit; 196 | assert (map[lit]); 197 | btorid = reft ? map[lit] : (map[lit] < 0 ? map[lit]+1 : map[lit]-1); 198 | fprintf (file, "%d root 1 %d\n", j++, btorid); 199 | } 200 | 201 | if (close_file) fclose (file); 202 | aiger_reset (aiger); 203 | 204 | return res; 205 | } 206 | -------------------------------------------------------------------------------- /aigmove.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (c) 2011, Armin Biere, Johannes Kepler University, Austria. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | ***************************************************************************/ 22 | 23 | #include "aiger.h" 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #define USAGE \ 33 | "usage: aigmove [-h][-v][-i][ []]\n" \ 34 | "\n" \ 35 | " -h print command line option summary\n" \ 36 | " -v increase verbosity\n" \ 37 | " -i ignore justice and fairness and thus produce old style format\n" \ 38 | " -r reverse move outputs to bad state constraint section\n" \ 39 | "\n" \ 40 | "Move all non-primary outputs to the ordinary output section.\n" \ 41 | "If a file already exists then 'aigmove' aborts unless\n" \ 42 | "it is forced to overwrite it by specifying '-f'.\n" 43 | 44 | static aiger * src, * dst; 45 | static unsigned valid, bad, latch, prev; 46 | static int verbose, ignore, reverse; 47 | 48 | static void die (const char *fmt, ...) { 49 | va_list ap; 50 | fputs ("*** [aigmove] ", stderr); 51 | va_start (ap, fmt); 52 | vfprintf (stderr, fmt, ap); 53 | va_end (ap); 54 | fputc ('\n', stderr); 55 | fflush (stderr); 56 | exit (1); 57 | } 58 | 59 | static void msg (const char *fmt, ...) { 60 | va_list ap; 61 | if (!verbose) 62 | return; 63 | fputs ("[aigmove] ", stderr); 64 | va_start (ap, fmt); 65 | vfprintf (stderr, fmt, ap); 66 | va_end (ap); 67 | fputc ('\n', stderr); 68 | fflush (stderr); 69 | } 70 | 71 | static unsigned next () { return 2*(dst->maxvar+1); } 72 | 73 | int main (int argc, char ** argv) { 74 | const char * input, * output, * err; 75 | aiger_and * a; 76 | unsigned j; 77 | int i, ok; 78 | 79 | input = output = 0; 80 | 81 | for (i = 1; i < argc; i++) { 82 | if (!strcmp (argv[i], "-h")) { printf ("%s", USAGE); exit (0); } 83 | else if (!strcmp (argv[i], "-v")) verbose = 1; 84 | else if (!strcmp (argv[i], "-i")) ignore = 1; 85 | else if (!strcmp (argv[i], "-r")) reverse = 1; 86 | else if (argv[i][0] == '-') 87 | die ("invalid command line option '%s'", argv[i]); 88 | else if (output) die ("too many arguments"); 89 | else if (input) output = argv[i]; 90 | else input = argv[i]; 91 | } 92 | 93 | src = aiger_init (); 94 | if (input) { 95 | msg ("reading '%s'", input); 96 | err = aiger_open_and_read_from_file (src, input); 97 | } else { 98 | msg ("reading ''"); 99 | err = aiger_read_from_file (src, stdin); 100 | } 101 | 102 | if (err) die ("read error: %s", err); 103 | 104 | msg ("read MILOA %u %u %u %u %u BCJF %u %u %u %u", 105 | src->maxvar, 106 | src->num_inputs, src->num_latches, src->num_outputs, src->num_ands, 107 | src->num_bad, src->num_constraints, src->num_justice, src->num_fairness); 108 | 109 | if (!ignore && src->num_justice) 110 | die ("will not ignore justice properties (use '-i')"); 111 | if (!ignore && src->num_fairness) 112 | die ("will not ignore fairness properties (use '-i')"); 113 | 114 | if (!reverse && src->num_outputs && 115 | !src->num_bad && !src->num_constraints && 116 | !src->num_justice && !src->num_fairness) 117 | die ("only outputs founds (use '-r' for reverse move)"); 118 | 119 | dst = aiger_init (); 120 | for (j = 0; j < src->num_inputs; j++) 121 | aiger_add_input (dst, src->inputs[j].lit, src->inputs[j].name); 122 | for (j = 0; j < src->num_latches; j++) { 123 | aiger_add_latch (dst, 124 | src->latches[j].lit, src->latches[j].next, src->latches[j].name); 125 | aiger_add_reset (dst, src->latches[j].lit, src->latches[j].reset); 126 | } 127 | for (j = 0; j < src->num_ands; j++) { 128 | a = src->ands + j; 129 | aiger_add_and (dst, a->lhs, a->rhs0, a->rhs1); 130 | } 131 | 132 | if (reverse) { 133 | for (j = 0; j < src->num_outputs; j++) 134 | aiger_add_bad (dst, src->outputs[j].lit, src->outputs[j].name); 135 | } else { 136 | for (j = 0; j < src->num_outputs; j++) 137 | aiger_add_output (dst, src->outputs[j].lit, src->outputs[j].name); 138 | 139 | if (src->num_bad && src->num_constraints) { 140 | if (src->num_latches) { 141 | latch = next (); 142 | valid = latch + 2*src->num_constraints; 143 | aiger_add_latch (dst, latch, 144 | aiger_not (valid), "AIGMOVE_INVALID_LATCH"); 145 | prev = aiger_not (latch); 146 | for (j = 0; j < src->num_constraints; j++) { 147 | unsigned tmp = latch + 2*(j+1); 148 | aiger_add_and (dst, tmp, prev, src->constraints[j].lit); 149 | prev = tmp; 150 | } 151 | assert (prev == valid); 152 | } else { 153 | valid = src->constraints[0].lit; 154 | for (j = 1; j < src->num_constraints; j++) { 155 | unsigned tmp = next (); 156 | aiger_add_and (dst, tmp, valid, src->constraints[j].lit); 157 | valid = tmp; 158 | } 159 | } 160 | for (j = 0; j < src->num_bad; j++) { 161 | bad = next (); 162 | aiger_add_and (dst, bad, valid, src->bad[j].lit); 163 | aiger_add_output (dst, bad, src->bad[j].name); 164 | } 165 | } else 166 | for (j = 0; j < src->num_bad; j++) 167 | aiger_add_output (dst, src->bad[j].lit, src->bad[j].name); 168 | } 169 | 170 | aiger_reset (src); 171 | 172 | msg ("write MILOA %u %u %u %u %u BCJF %u %u %u %u", 173 | dst->maxvar, 174 | dst->num_inputs, dst->num_latches, dst->num_outputs, dst->num_ands, 175 | dst->num_bad, dst->num_constraints, dst->num_justice, dst->num_fairness); 176 | 177 | if (output) { 178 | msg ("writing '%s'", output); 179 | ok = aiger_open_and_write_to_file (dst, output); 180 | } else { 181 | msg ("writing ''", output); 182 | ok = aiger_write_to_file (dst, 183 | (isatty (1) ? aiger_ascii_mode : aiger_binary_mode), stdout); 184 | } 185 | if (!ok) die ("write error"); 186 | 187 | aiger_reset (dst); 188 | 189 | return 0; 190 | } 191 | -------------------------------------------------------------------------------- /aigunconstraint.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (c) 2025 Armin Biere, University of Freiburg. 3 | Copyright (c) 2013 - 2020 Armin Biere, Johannes Kepler University. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to 7 | deal in the Software without restriction, including without limitation the 8 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9 | sell copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | IN THE SOFTWARE. 22 | ***************************************************************************/ 23 | 24 | #include "aiger.h" 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | static const char * USAGE = 33 | "usage: aigunconstraint [-h][-v] [ []]\n" 34 | "\n" 35 | " -h print this command line option summary\n" 36 | " -q quiet (no warnings)\n" 37 | " -v increase verbosity\n" 38 | "\n" 39 | "The input is assumed to have bad state and constraint properties.\n" 40 | "The constraints are eliminated by adding a latch.\n" 41 | ; 42 | 43 | static aiger * src, * dst; 44 | static int verbose; 45 | 46 | static void die (const char *fmt, ...) { 47 | va_list ap; 48 | fputs ("*** [aigunconstraint] error: ", stderr); 49 | va_start (ap, fmt); 50 | vfprintf (stderr, fmt, ap); 51 | va_end (ap); 52 | fputc ('\n', stderr); 53 | fflush (stderr); 54 | exit (1); 55 | } 56 | 57 | static void warn (const char *fmt, ...) { 58 | if (verbose < 0) return; 59 | va_list ap; 60 | fputs ("*** [aigunconstraint] warning: ", stderr); 61 | va_start (ap, fmt); 62 | vfprintf (stderr, fmt, ap); 63 | va_end (ap); 64 | fputc ('\n', stderr); 65 | fflush (stderr); 66 | } 67 | 68 | static void msg (const char *fmt, ...) { 69 | va_list ap; 70 | if (verbose <= 0) return; 71 | fputs ("[aigunconstraint] ", stderr); 72 | va_start (ap, fmt); 73 | vfprintf (stderr, fmt, ap); 74 | va_end (ap); 75 | fputc ('\n', stderr); 76 | fflush (stderr); 77 | } 78 | 79 | static unsigned maxvar; 80 | 81 | static unsigned newlit () { 82 | unsigned res; 83 | if (!maxvar) { assert (dst); maxvar = dst->maxvar; } 84 | res = ++maxvar; 85 | return 2*res; 86 | } 87 | 88 | int main (int argc, char ** argv) { 89 | unsigned invalid_state, constraints_valid; 90 | const char * input, * output, * err; 91 | unsigned j, tmp; 92 | aiger_and * a; 93 | int i, ok; 94 | 95 | input = output = 0; 96 | 97 | for (i = 1; i < argc; i++) { 98 | if (!strcmp (argv[i], "-h")) { printf ("%s", USAGE); exit (0); } 99 | else if (!strcmp (argv[i], "-v")) verbose = 1; 100 | else if (!strcmp (argv[i], "-q")) verbose = -1; 101 | else if (argv[i][0] == '-') 102 | die ("invalid command line option '%s'", argv[i]); 103 | else if (output) die ("too many arguments"); 104 | else if (input) output = argv[i]; 105 | else input = argv[i]; 106 | } 107 | 108 | src = aiger_init (); 109 | if (input) { 110 | msg ("reading '%s'", input); 111 | err = aiger_open_and_read_from_file (src, input); 112 | } else { 113 | msg ("reading ''"); 114 | err = aiger_read_from_file (src, stdin); 115 | } 116 | 117 | if (err) die ("read error: %s", err); 118 | 119 | msg ("read MILOA %u %u %u %u %u BCJF %u %u %u %u", 120 | src->maxvar, 121 | src->num_inputs, 122 | src->num_latches, 123 | src->num_outputs, 124 | src->num_ands, 125 | src->num_bad, 126 | src->num_constraints, 127 | src->num_justice, 128 | src->num_fairness); 129 | 130 | const char * input_path = input ? input : ""; 131 | if (src->num_outputs) 132 | die ("can not handle outputs in '%s'", input_path); 133 | if (!src->num_bad) 134 | die ("no bad state properties in '%s'", input_path); 135 | 136 | if (!src->num_constraints) { 137 | warn ("no environment constraints in '%s'", input_path); 138 | dst = src; 139 | goto COPY; 140 | } 141 | 142 | if (src->num_justice) 143 | die ("can not handle justice properties in '%s'", input_path); 144 | 145 | dst = aiger_init (); 146 | 147 | for (j = 0; j < src->num_inputs; j++) 148 | aiger_add_input (dst, src->inputs[j].lit, src->inputs[j].name); 149 | 150 | for (j = 0; j < src->num_ands; j++) { 151 | aiger_and * a = src->ands + j; 152 | aiger_add_and (dst, a->lhs, a->rhs0, a->rhs1); 153 | } 154 | 155 | for (j = 0; j < src->num_latches; j++) { 156 | aiger_symbol * s = src->latches + j; 157 | aiger_add_latch (dst, s->lit, s->next, s->name); 158 | if (s->reset) aiger_add_reset (dst, s->lit, s->reset); 159 | } 160 | 161 | msg ("initialized copy of original aiger model"); 162 | 163 | invalid_state = newlit (); 164 | constraints_valid = aiger_not (invalid_state); 165 | 166 | for (j = 0; j < src->num_constraints; j++) { 167 | tmp = newlit (); 168 | aiger_add_and (dst, tmp, constraints_valid, src->constraints[j].lit); 169 | constraints_valid = tmp; 170 | } 171 | 172 | aiger_add_latch (dst, 173 | invalid_state, 174 | aiger_not (constraints_valid), 175 | "AIGUNCONSTRAINT_INVALID_STATE"); 176 | 177 | msg ("added one latch and %u AND gates for its next state function", 178 | src->num_constraints); 179 | 180 | for (j = 0; j < src->num_bad; j++) { 181 | tmp = newlit (); 182 | aiger_add_and (dst, tmp, constraints_valid, src->bad[j].lit); 183 | aiger_add_bad (dst, tmp, src->bad[j].name); 184 | } 185 | 186 | msg ("added %u AND gates as guards for %u bad state properties", 187 | src->num_bad, src->num_bad); 188 | 189 | aiger_reset (src); 190 | 191 | COPY: 192 | 193 | aiger_reencode (dst); 194 | 195 | msg ("write MILOA %u %u %u %u %u BCJF %u %u %u %u", 196 | dst->maxvar, 197 | dst->num_inputs, 198 | dst->num_latches, 199 | dst->num_outputs, 200 | dst->num_ands, 201 | dst->num_bad, 202 | dst->num_constraints, 203 | dst->num_justice, 204 | dst->num_fairness); 205 | 206 | if (output) { 207 | msg ("writing '%s'", output); 208 | ok = aiger_open_and_write_to_file (dst, output); 209 | } else { 210 | msg ("writing ''", output); 211 | ok = aiger_write_to_file (dst, 212 | (isatty (1) ? aiger_ascii_mode : aiger_binary_mode), stdout); 213 | } 214 | if (!ok) die ("write error"); 215 | 216 | aiger_reset (dst); 217 | 218 | return 0; 219 | } 220 | -------------------------------------------------------------------------------- /soltostim.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (c) 2006-2007, Armin Biere, Johannes Kepler University. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | ***************************************************************************/ 22 | 23 | #include "aiger.h" 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | static aiger *model; 33 | 34 | static const char *solution_file_name; 35 | static FILE *solution_file; 36 | static int close_solution_file; 37 | static int lineno; 38 | static int prev; 39 | 40 | static int *solution; 41 | static unsigned size_solution; 42 | static unsigned count_solution; 43 | 44 | static int size_assignment; 45 | static int *assignment; 46 | 47 | static void 48 | die (const char *fmt, ...) 49 | { 50 | va_list ap; 51 | fputs ("*** soltostim: ", stderr); 52 | va_start (ap, fmt); 53 | vfprintf (stderr, fmt, ap); 54 | va_end (ap); 55 | fputc ('\n', stdout); 56 | exit (1); 57 | } 58 | 59 | static void 60 | push (int lit) 61 | { 62 | if (count_solution == size_solution) 63 | { 64 | size_solution = size_solution ? 2 * size_solution : 1; 65 | solution = realloc (solution, sizeof (solution[0]) * size_solution); 66 | } 67 | 68 | solution[count_solution++] = lit; 69 | } 70 | 71 | static int 72 | next (void) 73 | { 74 | int ch = getc (solution_file); 75 | if (prev == '\n') 76 | lineno++; 77 | prev = ch; 78 | return ch; 79 | } 80 | 81 | static int 82 | match (const char *str) 83 | { 84 | const char *p; 85 | 86 | for (p = str; *p; p++) 87 | if (*p != next ()) 88 | return 0; 89 | 90 | return 1; 91 | } 92 | 93 | static void 94 | perr (const char *msg) 95 | { 96 | die ("%s: line %d: %s", solution_file_name, lineno, msg); 97 | } 98 | 99 | static void 100 | parse (void) 101 | { 102 | int ch, lit, sign; 103 | 104 | lineno = 0; 105 | prev = '\n'; 106 | 107 | SKIP_COMMENTS_UNTIL_SOLUTION_START: 108 | 109 | ch = next (); 110 | if (ch == 's') 111 | goto SOLUTION_START; 112 | 113 | if (ch == 'c') 114 | { 115 | while ((ch = next ()) != '\n' && ch != EOF) 116 | ; 117 | 118 | if (ch == EOF) 119 | die ("%s: no solution line found", solution_file_name); 120 | 121 | goto SKIP_COMMENTS_UNTIL_SOLUTION_START; 122 | } 123 | 124 | perr ("expected 's' or 'c' at line start"); 125 | 126 | SOLUTION_START: 127 | 128 | ch = next (); 129 | if (ch != ' ') 130 | INVALID_SOLUTION_LINE: 131 | perr ("invalid solution line"); 132 | 133 | ch = next (); 134 | 135 | if (ch != 'S') 136 | { 137 | if (ch == 'U') 138 | { 139 | ch = next (); 140 | if (ch != 'N') 141 | goto INVALID_SOLUTION_LINE; 142 | 143 | ch = next (); 144 | if (ch == 'K') 145 | { 146 | if (!match ("NOWN\n")) 147 | goto INVALID_SOLUTION_LINE; 148 | 149 | EXPECTED_SATISFIABLE_SOLUTION: 150 | perr ("expected 's SATISFIABLE'"); 151 | } 152 | else if (ch == 'S') 153 | { 154 | if (!match ("ATISFIABLE\n")) 155 | goto INVALID_SOLUTION_LINE; 156 | 157 | goto EXPECTED_SATISFIABLE_SOLUTION; 158 | } 159 | else 160 | goto INVALID_SOLUTION_LINE; 161 | } 162 | else 163 | goto INVALID_SOLUTION_LINE; 164 | } 165 | 166 | if (!match ("ATISFIABLE\n")) 167 | goto INVALID_SOLUTION_LINE; 168 | 169 | SCAN_SOLUTION: 170 | ch = next (); 171 | if (ch != 'v') 172 | UNTERMINATED_SOLUTION: 173 | perr ("terminating '0' missing"); 174 | 175 | SCAN_LITERAL: 176 | ch = next (); 177 | 178 | SCAN_LITERAL_AFTER_READING_CH: 179 | if (ch == ' ' || ch == '\t') 180 | goto SCAN_LITERAL; 181 | 182 | if (ch == EOF) 183 | goto UNTERMINATED_SOLUTION; 184 | 185 | if (ch == '\n') 186 | goto SCAN_SOLUTION; 187 | 188 | if (ch == '-') 189 | { 190 | sign = -1; 191 | ch = next (); 192 | } 193 | else 194 | sign = 1; 195 | 196 | if (!isdigit (ch)) 197 | perr ("expected literal"); 198 | 199 | lit = ch - '0'; 200 | while (isdigit (ch = next ())) 201 | lit = 10 * lit + (ch - '0'); 202 | 203 | if (!lit) 204 | return; 205 | 206 | lit *= sign; 207 | push (lit); 208 | 209 | goto SCAN_LITERAL_AFTER_READING_CH; 210 | } 211 | 212 | static void 213 | assign (void) 214 | { 215 | int i, tmp; 216 | 217 | size_assignment = 0; 218 | for (i = 0; i < count_solution; i++) 219 | { 220 | tmp = abs (solution[i]); 221 | if (size_assignment < tmp) 222 | size_assignment = tmp; 223 | } 224 | 225 | size_assignment++; 226 | assignment = calloc (size_assignment, sizeof (assignment[0])); 227 | 228 | for (i = 0; i < count_solution; i++) 229 | { 230 | tmp = solution[i]; 231 | assignment[abs (tmp)] = tmp; 232 | } 233 | } 234 | 235 | static int 236 | deref (unsigned idx) 237 | { 238 | assert (idx); 239 | assert (idx <= model->maxvar); 240 | 241 | return idx >= size_assignment ? 0 : assignment[idx]; 242 | } 243 | 244 | static void 245 | print (void) 246 | { 247 | unsigned i, idx; 248 | char ch; 249 | int tmp; 250 | 251 | for (i = 0; i < model->num_inputs; i++) 252 | { 253 | idx = model->inputs[i].lit / 2; 254 | tmp = deref (idx); 255 | if (tmp < 0) 256 | ch = '0'; 257 | else if (tmp > 0) 258 | ch = '1'; 259 | else 260 | ch = 'x'; 261 | 262 | fputc (ch, stdout); 263 | } 264 | 265 | fputc ('\n', stdout); 266 | } 267 | 268 | static const char *USAGE = 269 | "usage: soltostim [-h] [ ]\n"; 270 | 271 | int 272 | main (int argc, char **argv) 273 | { 274 | const char *model_file_name, *err; 275 | int i; 276 | 277 | solution_file_name = model_file_name = 0; 278 | 279 | for (i = 1; i < argc; i++) 280 | { 281 | if (!strcmp (argv[i], "-h")) 282 | { 283 | fputs (USAGE, stdout); 284 | exit (1); 285 | } 286 | else if (argv[i][0] == '-') 287 | die ("invalid command line option '%s'", argv[i]); 288 | else if (solution_file_name) 289 | die ("more than two files on command line"); 290 | else if (model_file_name) 291 | solution_file_name = argv[i]; 292 | else 293 | model_file_name = argv[i]; 294 | } 295 | 296 | if (!model_file_name) 297 | die ("no model specified"); 298 | 299 | model = aiger_init (); 300 | if ((err = aiger_open_and_read_from_file (model, model_file_name))) 301 | die ("%s: %s", model_file_name, err); 302 | 303 | if (solution_file_name) 304 | { 305 | if (!(solution_file = fopen (solution_file_name, "r"))) 306 | die ("failed to read '%s'", solution_file_name); 307 | 308 | close_solution_file = 1; 309 | } 310 | else 311 | { 312 | solution_file = stdin; 313 | solution_file_name = ""; 314 | } 315 | 316 | parse (); 317 | assign (); 318 | print (); 319 | 320 | if (close_solution_file) 321 | fclose (solution_file); 322 | 323 | aiger_reset (model); 324 | free (solution); 325 | free (assignment); 326 | 327 | return 0; 328 | } 329 | -------------------------------------------------------------------------------- /wrapstim.c: -------------------------------------------------------------------------------- 1 | #include "aiger.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | static unsigned k; 11 | static int foundk; 12 | 13 | static aiger *model; 14 | static const char *model_file_name; 15 | static unsigned **m2e; 16 | 17 | static aiger *expansion; 18 | static const char *expansion_file_name; 19 | static char *assignment; 20 | 21 | static const char *stimulus_file_name; 22 | static int close_stimulus_file; 23 | static FILE *stimulus_file; 24 | 25 | static void 26 | die (const char *fmt, ...) 27 | { 28 | va_list ap; 29 | fputs ("*** [wrapstim] ", stderr); 30 | va_start (ap, fmt); 31 | vfprintf (stderr, fmt, ap); 32 | va_end (ap); 33 | fputc ('\n', stderr); 34 | exit (1); 35 | } 36 | 37 | static void 38 | link (void) 39 | { 40 | const char *p, *start_of_name, *end_of_name, *q; 41 | aiger_symbol *esym, *msym; 42 | unsigned i, mpos, epos; 43 | char ch; 44 | 45 | m2e = malloc (sizeof (m2e[0]) * model->num_inputs); 46 | for (mpos = 0; mpos < model->num_inputs; mpos++) 47 | m2e[mpos] = calloc (k + 1, sizeof (m2e[mpos][0])); 48 | 49 | for (epos = 0; epos < expansion->num_inputs; epos++) 50 | { 51 | esym = expansion->inputs + epos; 52 | p = esym->name; 53 | if (!p) 54 | die ("input %u does not have an expanded symbol in '%s'", 55 | epos, expansion_file_name); 56 | 57 | ch = *p++; 58 | if (!isdigit (ch)) 59 | die ("symbol for input %u of '%s' does not have a time prefix", 60 | epos, expansion_file_name); 61 | 62 | i = ch - '0'; 63 | while (isdigit (ch = *p++)) 64 | i = 10 * i + (ch - '0'); 65 | 66 | if (i > k) 67 | die ("time prefix %u of input %u in '%s' exceeds bound %u", 68 | i, epos, expansion_file_name, k); 69 | 70 | if (ch != ' ') 71 | SPACE_MISSING: 72 | die ("symbol of input %u of '%s' is missing a space seperator", 73 | epos, expansion_file_name); 74 | 75 | start_of_name = p; 76 | while (*p++) 77 | ; 78 | 79 | while (*--p != ' ') /* we have ' ' as sentinel */ 80 | ; 81 | 82 | end_of_name = p; 83 | if (end_of_name < start_of_name) 84 | goto SPACE_MISSING; 85 | 86 | mpos = 0; 87 | while ((ch = *++p)) 88 | { 89 | if (!isdigit (ch)) 90 | die ("invalid position suffix in symbol for input %u of '%s'", 91 | epos, expansion_file_name); 92 | 93 | mpos = 10 * mpos + (ch - '0'); 94 | } 95 | 96 | assert (i <= k); 97 | if (mpos >= model->num_inputs) 98 | die ("invalid model position %u in symbol of input %u of '%s'", 99 | mpos, epos, expansion_file_name); 100 | 101 | if (m2e[mpos][i]) 102 | die ("input %u of '%s' at time %u expanded twice in '%s'", 103 | mpos, model_file_name, i, expansion_file_name); 104 | 105 | msym = model->inputs + mpos; 106 | if (msym->name) 107 | { 108 | for (p = start_of_name, q = msym->name; 109 | p < end_of_name && *q && *p == *q; p++, q++) 110 | ; 111 | 112 | if ((p == end_of_name) != !*q) 113 | die ("symbol of input %u in '%s' " 114 | "does not match its expansion at time %u in '%s'", 115 | mpos, model_file_name, i, expansion_file_name); 116 | } 117 | 118 | m2e[mpos][i] = epos + 1; /* 0 reserved for 'x' */ 119 | } 120 | } 121 | 122 | static void 123 | parse (void) 124 | { 125 | unsigned epos; 126 | int ch; 127 | 128 | assignment = calloc (expansion->num_inputs + 1, sizeof (assignment[0])); 129 | assignment[0] = 'x'; 130 | 131 | for (epos = 0; epos < expansion->num_inputs; epos++) 132 | { 133 | ch = getc (stimulus_file); 134 | 135 | if (ch == EOF || ch == '\n') 136 | die ("only got %u values out of %u in line 1 of '%s'", 137 | epos, expansion->num_inputs, stimulus_file_name); 138 | 139 | if (ch != '0' && ch != '1' && ch != 'x') 140 | die ("expected '0', '1', or 'x' at character %u in line 1 of '%s'", 141 | epos + 1, stimulus_file_name); 142 | 143 | assignment[epos + 1] = ch; 144 | } 145 | 146 | ch = getc (stimulus_file); 147 | if (ch != '\n') 148 | die ("expected new line after %u values in line 1 of '%s'", 149 | expansion->num_inputs, stimulus_file_name); 150 | 151 | ch = getc (stimulus_file); 152 | if (ch != EOF) 153 | die ("trailing characters after line 1 of '%s'", stimulus_file_name); 154 | } 155 | 156 | static void 157 | print (void) 158 | { 159 | unsigned i, mpos; 160 | 161 | for (i = 0; i <= k; i++) 162 | { 163 | for (mpos = 0; mpos < model->num_inputs; mpos++) 164 | fputc (assignment[m2e[mpos][i]], stdout); 165 | 166 | fputc ('\n', stdout); 167 | } 168 | } 169 | 170 | #define USAGE \ 171 | "usage: wrapstim [-h] []\n" \ 172 | "\n" \ 173 | "The is an AIG generated with 'aigbmc ' from\n" \ 174 | ". We assume that is a valid stimulus for \n" \ 175 | "as defined in the FORMAT report. Such a stimulus can for instance be\n" \ 176 | "obtained by translating the expanded AIG into a CNF with 'aigtocnf',\n" \ 177 | "running a SAT solver on the DIMACS file, and if the SAT solver\n" \ 178 | "returns a satisfying assignment, translating this solution back to\n" \ 179 | "a combinatioal stimulus file, consisting of exactly one input vector\n" \ 180 | "with the 'soltostim' tool. Putting all together we obtain a bounded\n" \ 181 | "model checker by using the following steps:\n" \ 182 | "\n" \ 183 | " aigbmc 17 model.aig expansion.aig\n" \ 184 | " aigtocnf expansion.aig expansion.cnf\n" \ 185 | " booleforce expansion.cnf > expansion.sol\n" \ 186 | " soltostim expansion.aig expansion.sol > expansion.stim\n" \ 187 | " wrapstim model.aig expansion.aig 17 expansion.stim > model.stim\n" \ 188 | "\n" \ 189 | "We assume of course that the SAT solver produces a satisfying assignment.\n" \ 190 | "The final result is now a valid stimulus file for the original model.\n" \ 191 | "We can simulate it by for instance 'aigsim -v model.aig model.stim'\n" \ 192 | "which would due to the usage of the '-v' option even produce a VCD file.\n" 193 | 194 | int 195 | main (int argc, char **argv) 196 | { 197 | const char *err; 198 | int i; 199 | 200 | for (i = 1; i < argc; i++) 201 | { 202 | if (!strcmp (argv[i], "-h")) 203 | { 204 | fprintf (stderr, USAGE); 205 | exit (0); 206 | } 207 | else if (argv[i][0] == '-') 208 | die ("invalid command line option '%s'", argv[i]); 209 | else if (!model_file_name) 210 | model_file_name = argv[i]; 211 | else if (!expansion_file_name) 212 | expansion_file_name = argv[i]; 213 | else if (!foundk) 214 | { 215 | const char *p = argv[i]; 216 | while (*p) 217 | if (!isdigit (*p++)) 218 | die ("expected bound as third argument"); 219 | 220 | k = atoi (argv[i]); 221 | foundk = 1; 222 | } 223 | else if (!stimulus_file) 224 | stimulus_file_name = argv[i]; 225 | else 226 | die ("too many paramaters"); 227 | } 228 | 229 | if (!model_file_name) 230 | die ("no model specified"); 231 | 232 | if (!expansion_file_name) 233 | die ("no expansion specified"); 234 | 235 | if (!foundk) 236 | die ("unspecified bound"); 237 | 238 | model = aiger_init (); 239 | if ((err = aiger_open_and_read_from_file (model, model_file_name))) 240 | die ("%s", err); 241 | 242 | expansion = aiger_init (); 243 | if ((err = aiger_open_and_read_from_file (expansion, expansion_file_name))) 244 | die ("%s", err); 245 | 246 | link (); 247 | 248 | if (stimulus_file_name) 249 | { 250 | if (!(stimulus_file = fopen (stimulus_file_name, "r"))) 251 | die ("failed to read '%s'", stimulus_file_name); 252 | 253 | close_stimulus_file = 1; 254 | } 255 | else 256 | stimulus_file = stdin; 257 | 258 | parse (); 259 | 260 | if (close_stimulus_file) 261 | fclose (stimulus_file); 262 | 263 | aiger_reset (expansion); 264 | 265 | print (); 266 | 267 | for (i = 0; i < model->num_inputs; i++) 268 | free (m2e[i]); 269 | free (m2e); 270 | 271 | aiger_reset (model); 272 | 273 | return 0; 274 | } 275 | -------------------------------------------------------------------------------- /aigtodot.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (c) 2006-2007, Armin Biere, Johannes Kepler University. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | ***************************************************************************/ 22 | 23 | #include "aiger.h" 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | static void 32 | die (const char *fmt, ...) 33 | { 34 | va_list ap; 35 | fputs ("*** aigtodot: ", stderr); 36 | va_start (ap, fmt); 37 | vfprintf (stderr, fmt, ap); 38 | va_end (ap); 39 | fputc ('\n', stderr); 40 | exit (1); 41 | } 42 | 43 | #define LIT(L) (aiger_strip(L)/intlits) 44 | 45 | int 46 | main (int argc, char **argv) 47 | { 48 | const char *model_name, *dot_name, *err, * p; 49 | int i, close_dot_file, zero, strip, intlits; 50 | FILE *dot_file; 51 | aiger *model; 52 | char ch; 53 | 54 | model_name = dot_name = 0; 55 | intlits = 1; 56 | strip = 0; 57 | 58 | for (i = 1; i < argc; i++) 59 | { 60 | if (!strcmp (argv[i], "-h")) 61 | { 62 | fprintf (stderr, 63 | "usage: aigtodot [-h][-s][-i] [ []]\n" 64 | "\n" 65 | " -h print this command line option summary\n" 66 | " -s strip and do not show symbols\n" 67 | " -i use integer indices (divide literals by two)\n"); 68 | exit (0); 69 | } 70 | else if (!strcmp (argv[i], "-s")) 71 | strip = 1; 72 | else if (!strcmp (argv[i], "-i")) 73 | intlits = 2; 74 | else if (argv[i][0] == '-') 75 | die ("unknown command line option '%s'", argv[i]); 76 | else if (dot_name) 77 | die ("expected at most two file names on command line"); 78 | else if (model_name) 79 | dot_name = argv[i]; 80 | else 81 | model_name = argv[i]; 82 | } 83 | 84 | if (model_name && dot_name && !strcmp (model_name, dot_name)) 85 | die ("two identical file names given"); 86 | 87 | model = aiger_init (); 88 | if (model_name) 89 | err = aiger_open_and_read_from_file (model, model_name); 90 | else 91 | err = aiger_read_from_file (model, stdin); 92 | 93 | if (err) 94 | die ("%s", err); 95 | 96 | if (strip) 97 | aiger_strip_symbols_and_comments (model); 98 | 99 | if (dot_name) 100 | { 101 | dot_file = fopen (dot_name, "w"); 102 | if (!dot_file) 103 | die ("can not write to '%s'", dot_name); 104 | close_dot_file = 1; 105 | } 106 | else 107 | { 108 | dot_file = stdout; 109 | close_dot_file = 0; 110 | } 111 | 112 | fputs ("digraph \"", dot_file); 113 | if (model_name) 114 | { 115 | for (p = model_name; (ch = *p); p++) 116 | { 117 | if (ch == '"' || ch == '\\') /* mangle */ 118 | fputc ('\\', dot_file); 119 | 120 | fputc (ch, dot_file); 121 | } 122 | } 123 | else 124 | fputs ("", dot_file); 125 | 126 | fputs ("\" {\n", dot_file); 127 | 128 | for (i = 0; i < model->num_inputs; i++) 129 | { 130 | fprintf (dot_file, "\"%u\"[shape=box];\n", LIT(model->inputs[i].lit)); 131 | 132 | fprintf (dot_file, "I%u[shape=triangle,color=blue];\n", i); 133 | 134 | if (model->inputs[i].name) 135 | fprintf (dot_file, 136 | "I%u[label=\"%s\"];\n", 137 | i, model->inputs[i].name); 138 | 139 | fprintf (dot_file, 140 | "\"%u\"->I%u[arrowhead=none];\n", 141 | LIT(model->inputs[i].lit), i); 142 | } 143 | 144 | zero = 0; 145 | 146 | for (i = 0; i < model->num_ands; i++) 147 | { 148 | aiger_and *and = model->ands + i; 149 | 150 | fprintf (dot_file, "\"%u\"->\"%u\"[arrowhead=", 151 | LIT (and->lhs), LIT (and->rhs0)); 152 | fputs (((and->rhs0 & 1) ? "dot" : "none"), dot_file); 153 | fputs ("];\n", dot_file); 154 | 155 | fprintf (dot_file, "\"%u\"->\"%u\"[arrowhead=", 156 | LIT (and->lhs), LIT (and->rhs1)); 157 | fputs (((and->rhs1 & 1) ? "dot" : "none"), dot_file); 158 | fputs ("];\n", dot_file); 159 | 160 | if (and->rhs0 <= 1) 161 | zero = 1; 162 | 163 | if (and->rhs1 <= 1) 164 | zero = 1; 165 | } 166 | 167 | for (i = 0; i < model->num_outputs; i++) 168 | { 169 | fprintf (dot_file, "O%u[shape=triangle,color=blue];\n", i); 170 | 171 | if (model->outputs[i].name) 172 | fprintf (dot_file, 173 | "O%u[label=\"%s\"];\n", 174 | i, model->outputs[i].name); 175 | 176 | fprintf (dot_file, 177 | "O%u -> \"%u\"[arrowhead=", 178 | i, LIT (model->outputs[i].lit)); 179 | fputs ((((model->outputs[i].lit) & 1) ? "dot" : "none"), dot_file); 180 | fputs ("];\n", dot_file); 181 | 182 | if (model->outputs[i].lit <= 1) 183 | zero = 1; 184 | } 185 | 186 | for (i = 0; i < model->num_bad; i++) 187 | { 188 | fprintf (dot_file, "B%u[shape=triangle,color=red];\n", i); 189 | 190 | if (model->bad[i].name) 191 | fprintf (dot_file, 192 | "B%u[label=\"%s\"];\n", 193 | i, model->bad[i].name); 194 | 195 | fprintf (dot_file, 196 | "B%u -> \"%u\"[arrowhead=", 197 | i, LIT (model->bad[i].lit)); 198 | fputs ((((model->bad[i].lit) & 1) ? "dot" : "none"), dot_file); 199 | fputs ("];\n", dot_file); 200 | 201 | if (model->bad[i].lit <= 1) 202 | zero = 1; 203 | } 204 | 205 | for (i = 0; i < model->num_constraints; i++) 206 | { 207 | fprintf (dot_file, "C%u[shape=triangle,color=green];\n", i); 208 | 209 | if (model->constraints[i].name) 210 | fprintf (dot_file, 211 | "C%u[label=\"%s\"];\n", 212 | i, model->constraints[i].name); 213 | 214 | fprintf (dot_file, 215 | "C%u -> \"%u\"[arrowhead=", 216 | i, LIT (model->constraints[i].lit)); 217 | fputs ((((model->constraints[i].lit) & 1) ? "dot" : "none"), dot_file); 218 | fputs ("];\n", dot_file); 219 | 220 | if (model->constraints[i].lit <= 1) 221 | zero = 1; 222 | } 223 | 224 | for (i = 0; i < model->num_latches; i++) 225 | { 226 | fprintf (dot_file, 227 | "\"%u\"[shape=box,color=magenta];\n", 228 | LIT(model->latches[i].lit)); 229 | 230 | fprintf (dot_file, "L%u [shape=diamond,color=magenta];\n", i); 231 | 232 | if (model->latches[i].name) 233 | fprintf (dot_file, 234 | "L%u[label=\"%s\"];\n", 235 | i, model->latches[i].name); 236 | 237 | fprintf (dot_file, 238 | "L%u -> \"%u\"[arrowhead=", 239 | i, LIT (model->latches[i].next)); 240 | fputs ((((model->latches[i].next) & 1) ? "dot" : "none"), dot_file); 241 | fputs ("];\n", dot_file); 242 | 243 | fprintf (dot_file, 244 | "L%u -> \"%u\"[style=dashed,color=magenta,arrowhead=none];\n", 245 | i, LIT(model->latches[i].lit)); 246 | 247 | if (model->latches[i].next <= 1) 248 | zero = 1; 249 | } 250 | 251 | if (zero) 252 | fputs ("\"0\"[color=red,shape=box];\n", dot_file); 253 | 254 | fputs ("}\n", dot_file); 255 | 256 | if (close_dot_file) 257 | fclose (dot_file); 258 | 259 | aiger_reset (model); 260 | 261 | 262 | return 0; 263 | } 264 | -------------------------------------------------------------------------------- /aigunor.c: -------------------------------------------------------------------------------- 1 | // clang-format off 2 | 3 | static const char * usage = 4 | "usage: aigunor [ -h | -v | -x ] [ [ ]\n" 5 | "\n" 6 | "-h print this command line option summary\n" 7 | "-v enable verbose message (on 'stderr')\n" 8 | "-x stop at XOR gates too\n" 9 | "\n" 10 | "and ''\n" 11 | "is the input AIGER file. It is assumed to not have exactly one output\n" 12 | "which is then traversed recursively as long it forms an OR gate. If\n" 13 | "another AIG node is reached, which is not an OR gate it becomes a new\n" 14 | "output. The AIG with all those outputs is then written to ''.\n" 15 | "Without being specified, the input is taken as '' and the output\n" 16 | "as ''.\n" 17 | 18 | ; 19 | 20 | // clang-format on 21 | 22 | #include "aiger.h" 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | static int verbosity; 32 | static int stop_at_xor_gates; 33 | static const char *input_name; 34 | static const char *output_name; 35 | static struct aiger *input_model; 36 | static struct aiger *output_model; 37 | static unsigned num_new_outputs; 38 | static unsigned *new_outputs; 39 | static char *kept; 40 | 41 | static void die(const char *, ...) __attribute__((format(printf, 1, 2))); 42 | static void msg(const char *, ...) __attribute__((format(printf, 1, 2))); 43 | 44 | static void die(const char *fmt, ...) { 45 | fputs("aigunor: error: ", stderr); 46 | va_list ap; 47 | va_start(ap, fmt); 48 | vfprintf(stderr, fmt, ap); 49 | va_end(ap); 50 | fputc('\n', stderr); 51 | exit(1); 52 | } 53 | 54 | static void msg(const char *fmt, ...) { 55 | if (!verbosity) 56 | return; 57 | fputs("[aigunor] ", stderr); 58 | va_list ap; 59 | va_start(ap, fmt); 60 | vfprintf(stderr, fmt, ap); 61 | va_end(ap); 62 | fputc('\n', stderr); 63 | fflush(stderr); 64 | } 65 | static void traverse_rest(unsigned lit) { 66 | if (lit < 2) 67 | return; 68 | unsigned idx = aiger_lit2var(lit); 69 | if (kept[idx]) 70 | return; 71 | kept[idx] = 1; 72 | aiger_and *and = aiger_is_and(input_model, lit); 73 | assert(and); 74 | traverse_rest(and->rhs1); 75 | traverse_rest(and->rhs0); 76 | } 77 | 78 | static void add_new_output(unsigned lit) { 79 | assert(num_new_outputs <= input_model->maxvar); 80 | new_outputs[num_new_outputs++] = lit; 81 | } 82 | 83 | static int is_xor(aiger_and *and) { 84 | if (!aiger_sign(and->rhs0)) 85 | return 0; 86 | if (!aiger_sign(and->rhs1)) 87 | return 0; 88 | aiger_and *l = aiger_is_and(input_model, and->rhs0); 89 | if (!l) 90 | return 0; 91 | aiger_and *r = aiger_is_and(input_model, and->rhs1); 92 | if (!r) 93 | return 0; 94 | if (l->rhs0 == aiger_not(r->rhs0) && l->rhs1 == aiger_not(r->rhs1)) 95 | return 1; 96 | if (l->rhs0 == aiger_not(r->rhs1) && l->rhs1 == aiger_not(r->rhs0)) 97 | return 1; 98 | return 0; 99 | } 100 | 101 | static void traverse_top(unsigned lit) { 102 | if (lit < 2) 103 | add_new_output(lit); 104 | else if (aiger_is_input(input_model, lit)) 105 | add_new_output(lit); 106 | else { 107 | aiger_and *and = aiger_is_and(input_model, lit); 108 | assert(and); 109 | if (aiger_sign(lit) && (!stop_at_xor_gates || !is_xor(and))) { 110 | traverse_top(aiger_not(and->rhs1)); 111 | traverse_top(aiger_not(and->rhs0)); 112 | } else { 113 | add_new_output(lit); 114 | traverse_rest(and->rhs1); 115 | traverse_rest(and->rhs0); 116 | unsigned idx = aiger_lit2var(lit); 117 | kept[idx] = 1; 118 | } 119 | } 120 | } 121 | 122 | int main(int argc, char **argv) { 123 | 124 | for (int i = 1; i != argc; i++) { 125 | const char *arg = argv[i]; 126 | if (!strcmp(arg, "-h")) { 127 | fputs(usage, stdout); 128 | return 0; 129 | } else if (!strcmp(arg, "-v")) 130 | verbosity = 1; 131 | else if (!strcmp(arg, "-x")) 132 | stop_at_xor_gates = 1; 133 | else if (arg[0] == '-' && arg[1]) 134 | die("invalid option '%s' (try '-h')", arg); 135 | else if (!input_name) 136 | input_name = arg; 137 | else if (!output_name) 138 | output_name = arg; 139 | else 140 | die("too many files '%s', '%s' and '%s' (try '-h')", input_name, 141 | output_name, arg); 142 | } 143 | 144 | if (input_name && !strcmp(input_name, "-")) 145 | input_name = 0; 146 | if (output_name && !strcmp(output_name, "-")) 147 | output_name = 0; 148 | if (input_name && output_name && !strcmp(input_name, output_name)) 149 | die("can not read and write to the same file '%s'", input_name); 150 | 151 | input_model = aiger_init(); 152 | 153 | if (input_name) { 154 | msg("reading input model from '%s'", input_name); 155 | const char *read_error = 156 | aiger_open_and_read_from_file(input_model, input_name); 157 | if (read_error) 158 | die("parse error in '%s': %s", input_name, read_error); 159 | } else { 160 | msg("reading input model from ''"); 161 | const char *read_error = aiger_read_from_file(input_model, stdin); 162 | die("parse error in '': %s", read_error); 163 | } 164 | 165 | if (input_model->num_outputs != 1) 166 | die("expected exactly one output (but got '%u')", input_model->num_outputs); 167 | 168 | if (input_model->num_latches) 169 | die("unsupported '%u' latches", input_model->num_latches); 170 | if (input_model->num_bad) 171 | die("unsupported '%u' bad properties", input_model->num_bad); 172 | if (input_model->num_constraints) 173 | die("unsupported '%u' environment constraints", 174 | input_model->num_constraints); 175 | if (input_model->num_fairness) 176 | die("unsupported '%u' fairness constraints", input_model->num_fairness); 177 | if (input_model->num_justice) 178 | die("unsupported '%u' justice properties", input_model->num_justice); 179 | 180 | msg("parsed 'MILOA' header '%u %u %u %u %u'", input_model->maxvar, 181 | input_model->num_inputs, input_model->num_latches, 182 | input_model->num_outputs, input_model->num_ands); 183 | 184 | struct aiger *output_model = aiger_init(); 185 | 186 | kept = calloc(input_model->maxvar + 1, 1); 187 | for (unsigned i = 0; i != input_model->num_inputs; i++) { 188 | aiger_symbol *input = input_model->inputs + i; 189 | aiger_add_input(output_model, input->lit, input->name); 190 | unsigned idx = aiger_lit2var(input->lit); 191 | kept[idx] = 1; 192 | } 193 | 194 | new_outputs = calloc(input_model->maxvar + 1, sizeof *new_outputs); 195 | for (unsigned i = 0; i != input_model->num_outputs; i++) { 196 | aiger_symbol *output = input_model->outputs + i; 197 | traverse_top(output->lit); 198 | } 199 | 200 | for (unsigned idx = 1; idx <= input_model->maxvar; idx++) { 201 | if (!kept[idx]) 202 | continue; 203 | unsigned lit = aiger_var2lit(idx); 204 | if (aiger_is_input(input_model, lit)) 205 | continue; 206 | aiger_and *and = aiger_is_and(input_model, lit); 207 | assert(and); 208 | aiger_add_and(output_model, and->lhs, and->rhs0, and->rhs1); 209 | } 210 | 211 | assert(num_new_outputs); 212 | msg("split single output into '%u' new outputs", num_new_outputs); 213 | 214 | for (unsigned i = 0; i != num_new_outputs; i++) { 215 | unsigned lit = new_outputs[i]; 216 | aiger_add_output(output_model, lit, 0); 217 | } 218 | 219 | aiger_reset(input_model); 220 | 221 | if (output_name) { 222 | msg("writing output model to '%s'", output_name); 223 | if (!aiger_open_and_write_to_file(output_model, output_name)) 224 | die("could not open and write '%s'", output_name); 225 | } else { 226 | msg("writing output model to ''"); 227 | aiger_mode mode = isatty(1) ? aiger_ascii_mode : aiger_binary_mode; 228 | if (!aiger_write_to_file(output_model, mode, stdout)) 229 | die("failed to write to ''"); 230 | } 231 | 232 | msg("wrote 'MILOA' header '%u %u %u %u %u'", output_model->maxvar, 233 | output_model->num_outputs, output_model->num_latches, 234 | output_model->num_outputs, output_model->num_ands); 235 | 236 | aiger_reset(output_model); 237 | free(new_outputs); 238 | free(kept); 239 | 240 | return 0; 241 | } 242 | -------------------------------------------------------------------------------- /aigtosmv.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (c) 2006-2011, Armin Biere, Johannes Kepler University. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | ***************************************************************************/ 22 | 23 | #include "aiger.h" 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | static FILE *file; 32 | static aiger *mgr; 33 | static int count; 34 | 35 | static const char * prefix = ""; 36 | 37 | static void 38 | ps (const char *str) 39 | { 40 | fputs (str, file); 41 | } 42 | 43 | static void 44 | pl (unsigned lit) 45 | { 46 | const char *name; 47 | char ch; 48 | int i; 49 | 50 | if (lit == 0) 51 | fprintf (file, "FALSE"); 52 | else if (lit == 1) 53 | fprintf (file, "TRUE"); 54 | else if ((lit & 1)) 55 | putc ('!', file), pl (lit - 1); 56 | else 57 | { 58 | if (prefix) 59 | fputs (prefix, file); 60 | if ((name = aiger_get_symbol (mgr, lit))) 61 | { 62 | /* TODO: check name to be valid SMV name 63 | */ 64 | fputs (name, file); 65 | } 66 | else 67 | { 68 | if (aiger_is_input (mgr, lit)) 69 | ch = 'i'; 70 | else if (aiger_is_latch (mgr, lit)) 71 | ch = 'l'; 72 | else 73 | { 74 | assert (aiger_is_and (mgr, lit)); 75 | ch = 'a'; 76 | } 77 | 78 | for (i = 0; i <= count; i++) 79 | fputc (ch, file); 80 | 81 | fprintf (file, "%u", lit); 82 | } 83 | } 84 | } 85 | 86 | static int 87 | count_ch_prefix (const char *str, char ch) 88 | { 89 | const char *p; 90 | 91 | assert (ch); 92 | for (p = str; *p == ch; p++) 93 | ; 94 | 95 | if (*p && !isdigit (*p)) 96 | return 0; 97 | 98 | return p - str; 99 | } 100 | 101 | static void 102 | setupcount (void) 103 | { 104 | const char *symbol; 105 | unsigned i; 106 | int tmp; 107 | 108 | count = 0; 109 | for (i = 1; i <= mgr->maxvar; i++) 110 | { 111 | symbol = aiger_get_symbol (mgr, 2 * i); 112 | if (!symbol) 113 | continue; 114 | 115 | if ((tmp = count_ch_prefix (symbol, 'i')) > count) 116 | count = tmp; 117 | 118 | if ((tmp = count_ch_prefix (symbol, 'l')) > count) 119 | count = tmp; 120 | 121 | if ((tmp = count_ch_prefix (symbol, 'o')) > count) 122 | count = tmp; 123 | 124 | if ((tmp = count_ch_prefix (symbol, 'a')) > count) 125 | count = tmp; 126 | } 127 | } 128 | 129 | int 130 | main (int argc, char **argv) 131 | { 132 | const char *src, *dst, *error; 133 | int res, strip, bad; 134 | unsigned i, j; 135 | 136 | src = dst = 0; 137 | strip = 0; 138 | res = 0; 139 | bad = 0; 140 | 141 | for (i = 1; i < argc; i++) 142 | { 143 | if (!strcmp (argv[i], "-h")) 144 | { 145 | fprintf (stderr, 146 | "usage: aigtosmv [-h][-s][-p ][src [dst]]\n" 147 | "\n" 148 | " -h print this command line option summary\n" 149 | " -b assume outputs are bad properties\n" 150 | " -p use for variable names\n" 151 | " -s strip symbols\n" 152 | ); 153 | exit (0); 154 | } 155 | if (!strcmp (argv[i], "-s")) 156 | strip = 1; 157 | else if (!strcmp (argv[i], "-b")) 158 | bad = 1; 159 | else if (!strcmp (argv[i], "-p")) 160 | { 161 | if (++i == argc) 162 | { 163 | fprintf (stderr, "*** [aigtosmv] argument to '-p' missing\n"); 164 | exit (1); 165 | } 166 | 167 | prefix = argv[i]; 168 | } 169 | else if (argv[i][0] == '-') 170 | { 171 | fprintf (stderr, "*** [aigtosmv] invalid option '%s'\n", argv[i]); 172 | exit (1); 173 | } 174 | else if (!src) 175 | src = argv[i]; 176 | else if (!dst) 177 | dst = argv[i]; 178 | else 179 | { 180 | fprintf (stderr, "*** [aigtosmv] too many files\n"); 181 | exit (1); 182 | } 183 | } 184 | 185 | mgr = aiger_init (); 186 | 187 | if (src) 188 | error = aiger_open_and_read_from_file (mgr, src); 189 | else 190 | error = aiger_read_from_file (mgr, stdin); 191 | 192 | if (error) 193 | { 194 | fprintf (stderr, "*** [aigtosmv] %s\n", error); 195 | res = 1; 196 | } 197 | else 198 | { 199 | if (dst) 200 | { 201 | if (!(file = fopen (dst, "w"))) 202 | { 203 | fprintf (stderr, 204 | "*** [aigtosmv] failed to write to '%s'\n", dst); 205 | exit (1); 206 | } 207 | } 208 | else 209 | file = stdout; 210 | 211 | if (strip) 212 | aiger_strip_symbols_and_comments (mgr); 213 | else 214 | setupcount (); 215 | 216 | ps ("MODULE main\n"); 217 | ps ("VAR\n"); 218 | ps ("--inputs\n"); 219 | for (i = 0; i < mgr->num_inputs; i++) 220 | pl (mgr->inputs[i].lit), ps (" : boolean;\n"); 221 | ps ("--latches\n"); 222 | for (i = 0; i < mgr->num_latches; i++) 223 | pl (mgr->latches[i].lit), ps (" : boolean;\n"); 224 | ps ("ASSIGN\n"); 225 | for (i = 0; i < mgr->num_latches; i++) 226 | { 227 | if (mgr->latches[i].reset != mgr->latches[i].lit) { 228 | ps ("init("), pl (mgr->latches[i].lit), ps (") := "); 229 | pl(mgr->latches[i].reset), ps(";\n"); 230 | } 231 | ps ("next("), pl (mgr->latches[i].lit), ps (") := "); 232 | pl (mgr->latches[i].next), ps (";\n"); 233 | } 234 | ps ("DEFINE\n"); 235 | ps ("--ands\n"); 236 | for (i = 0; i < mgr->num_ands; i++) 237 | { 238 | aiger_and *n = mgr->ands + i; 239 | 240 | unsigned rhs0 = n->rhs0; 241 | unsigned rhs1 = n->rhs1; 242 | 243 | pl (n->lhs); 244 | ps (" := "); 245 | pl (rhs0); 246 | ps (" & "); 247 | pl (rhs1); 248 | ps (";\n"); 249 | } 250 | 251 | ps ("--outputs\n"); 252 | for (i = 0; i < mgr->num_outputs; i++) 253 | { 254 | for (j = 0; j <= count; j++) 255 | putc ('o', file); 256 | 257 | fprintf (file, "%u := ", i), pl (mgr->outputs[i].lit), ps (";\n"); 258 | } 259 | 260 | ps ("--bad\n"); 261 | if (bad) 262 | { 263 | for (i = 0; i < mgr->num_outputs; i++) 264 | { 265 | fprintf (file, "SPEC AG "); 266 | pl (aiger_not (mgr->outputs[i].lit)); 267 | fprintf (file, " --o%u as bad property\n", i); 268 | } 269 | } 270 | for (i = 0; i < mgr->num_bad; i++) 271 | { 272 | ps ("SPEC AG "); 273 | pl (aiger_not (mgr->bad[i].lit)); 274 | fprintf (file, " --b%u\n", i); 275 | } 276 | 277 | ps ("--constraints\n"); 278 | for (i = 0; i < mgr->num_constraints; i++) 279 | { 280 | fprintf (file, "INVAR "); 281 | pl (mgr->constraints[i].lit); 282 | fprintf (file, " --c%u\n", i); 283 | } 284 | 285 | ps ("--justice\n"); 286 | for (i = 0; i < mgr->num_justice; i++) 287 | { 288 | fprintf (file, "LTLSPEC !( --j%u\n", i); 289 | for (j = 0; j < mgr->justice[i].size; j++) 290 | { 291 | if (j) ps (" &\n"); 292 | ps ("(G F "); 293 | pl (mgr->justice[i].lits[j]); 294 | ps (")"); 295 | } 296 | ps (")\n"); 297 | } 298 | 299 | ps ("--fairness\n"); 300 | for (i = 0; i < mgr->num_fairness; i++) 301 | { 302 | ps ("FAIRNESS "); 303 | pl (mgr->fairness[i].lit); 304 | fprintf (file, " --f%u\n", i); 305 | } 306 | 307 | if (dst) 308 | fclose (file); 309 | } 310 | 311 | aiger_reset (mgr); 312 | 313 | return res; 314 | } 315 | -------------------------------------------------------------------------------- /testaigtoaig.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (c) 2006-2007, Armin Biere, Johannes Kepler University. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to 6 | deal in the Software without restriction, including without limitation the 7 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | IN THE SOFTWARE. 21 | ***************************************************************************/ 22 | 23 | #include "aiger.h" 24 | 25 | #include 26 | #include 27 | 28 | #ifdef NDEBUG 29 | #undef NDEBUG 30 | #endif 31 | 32 | #include 33 | 34 | static void 35 | init_and_reset (void) 36 | { 37 | aiger *aiger = aiger_init (); 38 | aiger_reset (aiger); 39 | } 40 | 41 | typedef struct test_memory_mgr test_memory_mgr; 42 | 43 | struct test_memory_mgr 44 | { 45 | size_t bytes; /* only the allocated bytes as state */ 46 | }; 47 | 48 | static void * 49 | test_malloc (test_memory_mgr * mgr, size_t bytes) 50 | { 51 | mgr->bytes += bytes; 52 | assert (mgr->bytes); 53 | return malloc (bytes); 54 | } 55 | 56 | static void 57 | test_free (test_memory_mgr * mgr, void *ptr, size_t bytes) 58 | { 59 | assert (mgr->bytes >= bytes); 60 | mgr->bytes -= bytes; 61 | free (ptr); 62 | } 63 | 64 | static test_memory_mgr mgr; 65 | 66 | static aiger * 67 | my_aiger_init (void) 68 | { 69 | return aiger_init_mem (&mgr, 70 | (aiger_malloc) test_malloc, (aiger_free) test_free); 71 | } 72 | 73 | static void 74 | init_and_reset_mem (void) 75 | { 76 | aiger *aiger = my_aiger_init (); 77 | aiger_reset (aiger); 78 | assert (!mgr.bytes); 79 | } 80 | 81 | static void 82 | only_add_and_reset (void) 83 | { 84 | aiger *aiger = my_aiger_init (); 85 | aiger_add_and (aiger, 4, 0, 1); 86 | aiger_add_input (aiger, 2, 0); 87 | aiger_add_output (aiger, 2, 0); 88 | aiger_add_output (aiger, 6, 0); 89 | aiger_add_latch (aiger, 6, 5, 0); 90 | aiger_reset (aiger); 91 | assert (!mgr.bytes); 92 | } 93 | 94 | static void 95 | latch_undefined (void) 96 | { 97 | aiger *aiger = my_aiger_init (); 98 | aiger_add_latch (aiger, 2, 5, 0); 99 | assert (aiger_check (aiger)); 100 | aiger_reset (aiger); 101 | assert (!mgr.bytes); 102 | } 103 | 104 | static void 105 | output_undefined (void) 106 | { 107 | aiger *aiger = my_aiger_init (); 108 | aiger_add_output (aiger, 2, 0); 109 | aiger_add_output (aiger, 6, 0); 110 | aiger_add_latch (aiger, 2, 5, 0); 111 | assert (aiger_check (aiger)); 112 | aiger_reset (aiger); 113 | assert (!mgr.bytes); 114 | } 115 | 116 | static void 117 | rhs_undefined (void) 118 | { 119 | aiger *aiger = my_aiger_init (); 120 | aiger_add_and (aiger, 4, 2, 1); 121 | assert (aiger_check (aiger)); 122 | aiger_reset (aiger); 123 | assert (!mgr.bytes); 124 | } 125 | 126 | static void 127 | cyclic0 (void) 128 | { 129 | aiger *aiger = my_aiger_init (); 130 | aiger_add_and (aiger, 4, 4, 1); 131 | assert (aiger_check (aiger)); 132 | aiger_reset (aiger); 133 | assert (!mgr.bytes); 134 | } 135 | 136 | static void 137 | cyclic1 (void) 138 | { 139 | aiger *aiger = my_aiger_init (); 140 | aiger_add_input (aiger, 2, 0); 141 | aiger_add_and (aiger, 4, 6, 2); 142 | aiger_add_and (aiger, 6, 4, 2); 143 | aiger_add_output (aiger, 5, 0); 144 | assert (aiger_check (aiger)); 145 | aiger_reset (aiger); 146 | assert (!mgr.bytes); 147 | } 148 | 149 | static void 150 | write_and_read_fmt (aiger * old, const char *name, const char *fmt) 151 | { 152 | char buffer[100]; 153 | aiger *new; 154 | assert (strlen (name) + strlen (fmt) + 5 < sizeof (buffer)); 155 | sprintf (buffer, "log/%s%s", name, fmt); 156 | assert (aiger_open_and_write_to_file (old, buffer)); 157 | new = aiger_init (); 158 | assert (!aiger_open_and_read_from_file (new, buffer)); 159 | aiger_reset (new); 160 | } 161 | 162 | static void 163 | write_and_read (aiger * old, const char *name) 164 | { 165 | write_and_read_fmt (old, name, ".aag"); 166 | write_and_read_fmt (old, name, ".aag.gz"); 167 | write_and_read_fmt (old, name, ".aig"); 168 | write_and_read_fmt (old, name, ".aig.gz"); 169 | } 170 | 171 | static char *empty_aig = "aag 0 0 0 0 0\n"; 172 | 173 | static void 174 | write_empty (void) 175 | { 176 | aiger *aiger = my_aiger_init (); 177 | char buffer[100]; 178 | assert (aiger_write_to_string (aiger, aiger_ascii_mode, buffer, 100)); 179 | assert (!strcmp (buffer, empty_aig)); 180 | write_and_read (aiger, "empty"); 181 | aiger_reset (aiger); 182 | assert (!mgr.bytes); 183 | } 184 | 185 | static char *false_aig = "aag 0 0 0 1 0\n0\n"; 186 | 187 | static void 188 | write_false (void) 189 | { 190 | aiger *aiger = my_aiger_init (); 191 | char buffer[100]; 192 | aiger_add_output (aiger, 0, 0); 193 | assert (aiger_write_to_string (aiger, aiger_ascii_mode, buffer, 100)); 194 | assert (!strcmp (buffer, false_aig)); 195 | aiger_reset (aiger); 196 | assert (!mgr.bytes); 197 | } 198 | 199 | static char *true_aig = "aag 0 0 0 1 0\n1\n"; 200 | 201 | static void 202 | write_true (void) 203 | { 204 | aiger *aiger = my_aiger_init (); 205 | char buffer[100]; 206 | aiger_add_output (aiger, 1, 0); 207 | assert (aiger_write_to_string (aiger, aiger_ascii_mode, buffer, 100)); 208 | assert (!strcmp (buffer, true_aig)); 209 | aiger_reset (aiger); 210 | assert (!mgr.bytes); 211 | } 212 | 213 | static char *and_aig = "aag 3 2 0 1 1\n2\n4\n6\n6 2 4\n"; 214 | 215 | static void 216 | write_and (void) 217 | { 218 | aiger *aiger = my_aiger_init (); 219 | char buffer[200]; 220 | aiger_add_input (aiger, 2, 0); 221 | aiger_add_input (aiger, 4, 0); 222 | aiger_add_output (aiger, 6, 0); 223 | aiger_add_and (aiger, 6, 2, 4); 224 | assert (aiger_write_to_string (aiger, aiger_ascii_mode, buffer, 200)); 225 | assert (!strcmp (buffer, and_aig)); 226 | aiger_reset (aiger); 227 | assert (!mgr.bytes); 228 | } 229 | 230 | static char *counter1 = 231 | "aag 8 2 1 1 4\n" 232 | "10\n" 233 | "4\n" 234 | "6 8\n" 235 | "8\n" 236 | "8 12 11\n" 237 | "12 17 15\n" 238 | "14 4 6\n" 239 | "16 5 7\n" 240 | "i0 reset\n" 241 | "i1 enable\n" 242 | "l0 latch\n" 243 | "o0 AIGER_NEVER\n" "c\n" "1-bit counter with reset and enable\n"; 244 | 245 | static char *counter1r = 246 | "aag 7 2 1 1 4\n" 247 | "2\n" 248 | "4\n" 249 | "6 14\n" 250 | "14\n" 251 | "8 6 4\n" 252 | "10 7 5\n" 253 | "12 11 9\n" 254 | "14 12 3\n" 255 | "i0 reset\n" 256 | "i1 enable\n" 257 | "l0 latch\n" 258 | "o0 AIGER_NEVER\n" "c\n" "1-bit counter with reset and enable\n"; 259 | 260 | static void 261 | reencode_counter1 (void) 262 | { 263 | aiger *aiger = my_aiger_init (); 264 | char buffer[200]; 265 | 266 | aiger_add_input (aiger, 10, "reset"); 267 | aiger_add_input (aiger, 4, "enable"); 268 | aiger_add_output (aiger, 8, "AIGER_NEVER"); 269 | 270 | aiger_add_latch (aiger, 6, 8, "latch"); 271 | 272 | aiger_add_and (aiger, 8, 12, 11); /* active high reset */ 273 | aiger_add_and (aiger, 12, 17, 15); /* latch ^ enable */ 274 | aiger_add_and (aiger, 14, 4, 6); 275 | aiger_add_and (aiger, 16, 5, 7); 276 | 277 | aiger_add_comment (aiger, "1-bit counter with reset and enable"); 278 | 279 | assert (aiger_write_to_string (aiger, aiger_ascii_mode, buffer, 200)); 280 | assert (!strcmp (buffer, counter1)); 281 | 282 | aiger_reencode (aiger); 283 | 284 | assert (aiger_write_to_string (aiger, aiger_ascii_mode, buffer, 200)); 285 | assert (!strcmp (buffer, counter1r)); 286 | 287 | write_and_read (aiger, "counter1"); 288 | 289 | aiger_reset (aiger); 290 | assert (!mgr.bytes); 291 | } 292 | 293 | int 294 | main (void) 295 | { 296 | init_and_reset (); 297 | init_and_reset_mem (); 298 | only_add_and_reset (); 299 | latch_undefined (); 300 | output_undefined (); 301 | rhs_undefined (); 302 | cyclic0 (); 303 | cyclic1 (); 304 | write_empty (); 305 | write_false (); 306 | write_true (); 307 | write_and (); 308 | reencode_counter1 (); 309 | return 0; 310 | } 311 | -------------------------------------------------------------------------------- /log/dp3.smv: -------------------------------------------------------------------------------- 1 | MODULE main 2 | VAR 3 | save : boolean; 4 | saved : boolean; 5 | turn_a_1 : boolean; --TYPE-- 1..3 6 | turn_a_0 : boolean; 7 | fork1_o_try___to___take___left : boolean; 8 | fork1_o_try___to___take___right : boolean; 9 | fork1_o_owner_a_1 : boolean; --TYPE-- 0..3 10 | fork1_o_owner_a_0 : boolean; 11 | fork1_o_loop_a_1 : boolean; --TYPE-- 0..3 12 | fork1_o_loop_a_0 : boolean; 13 | phil1_o_fair : boolean; 14 | phil1_o_state_a_0 : boolean; --TYPE-- eat think 15 | phil1_o_loop_a_0 : boolean; --TYPE-- eat think 16 | fork2_o_try___to___take___left : boolean; 17 | fork2_o_try___to___take___right : boolean; 18 | fork2_o_owner_a_1 : boolean; --TYPE-- 0..3 19 | fork2_o_owner_a_0 : boolean; 20 | fork2_o_loop_a_1 : boolean; --TYPE-- 0..3 21 | fork2_o_loop_a_0 : boolean; 22 | phil2_o_fair : boolean; 23 | phil2_o_state_a_0 : boolean; --TYPE-- eat think 24 | phil2_o_loop_a_0 : boolean; --TYPE-- eat think 25 | fork3_o_try___to___take___left : boolean; 26 | fork3_o_try___to___take___right : boolean; 27 | fork3_o_owner_a_1 : boolean; --TYPE-- 0..3 28 | fork3_o_owner_a_0 : boolean; 29 | fork3_o_loop_a_1 : boolean; --TYPE-- 0..3 30 | fork3_o_loop_a_0 : boolean; 31 | phil3_o_fair : boolean; 32 | phil3_o_state_a_0 : boolean; --TYPE-- eat think 33 | phil3_o_loop_a_0 : boolean; --TYPE-- eat think 34 | live : boolean; 35 | DEFINE 36 | fork1_o_looped := saved & (fork1_o_loop_a_0 <-> fork1_o_owner_a_0) & (fork1_o_loop_a_1 <-> fork1_o_owner_a_1); 37 | phil1_o_looped := saved & (phil1_o_loop_a_0 <-> phil1_o_state_a_0); 38 | fork2_o_looped := saved & (fork2_o_loop_a_0 <-> fork2_o_owner_a_0) & (fork2_o_loop_a_1 <-> fork2_o_owner_a_1); 39 | phil2_o_looped := saved & (phil2_o_loop_a_0 <-> phil2_o_state_a_0); 40 | fork3_o_looped := saved & (fork3_o_loop_a_0 <-> fork3_o_owner_a_0) & (fork3_o_loop_a_1 <-> fork3_o_owner_a_1); 41 | phil3_o_looped := saved & (phil3_o_loop_a_0 <-> phil3_o_state_a_0); 42 | found := !phil1_o_state_a_0; 43 | looped := phil1_o_looped & phil2_o_looped & phil3_o_looped; 44 | fair := phil1_o_fair & phil2_o_fair & phil3_o_fair; 45 | _o_MACRO0 := turn_a_1 | turn_a_0; 46 | _o_MACRO2 := fork1_o_owner_a_1 | fork1_o_owner_a_0; 47 | _o_MACRO1 := !phil3_o_state_a_0 | _o_MACRO2; 48 | _o_MACRO8 := !turn_a_1 & turn_a_0; 49 | _o_MACRO7 := _o_MACRO8 & _o_MACRO0; 50 | _o_MACRO6 := fork1_o_owner_a_0 <-> _o_MACRO7; 51 | _o_MACRO9 := fork1_o_owner_a_1 <-> !_o_MACRO0; 52 | _o_MACRO5 := _o_MACRO6 | _o_MACRO9; 53 | _o_MACRO4 := phil3_o_state_a_0 | _o_MACRO5; 54 | _o_MACRO3 := !_o_MACRO1 | _o_MACRO4; 55 | _o_MACRO10 := !_o_MACRO1 | !_o_MACRO4; 56 | _o_MACRO11 := !fork1_o_try___to___take___left | !turn_a_1; 57 | _o_MACRO12 := !phil1_o_state_a_0 | _o_MACRO2; 58 | _o_MACRO14 := phil1_o_state_a_0 | _o_MACRO5; 59 | _o_MACRO13 := !_o_MACRO12 | _o_MACRO14; 60 | _o_MACRO15 := !_o_MACRO12 | !_o_MACRO14; 61 | _o_MACRO18 := turn_a_1 & !turn_a_0; 62 | _o_MACRO17 := fork1_o_try___to___take___left & _o_MACRO18; 63 | _o_MACRO19 := !fork1_o_try___to___take___right | turn_a_1; 64 | _o_MACRO16 := _o_MACRO17 | _o_MACRO19; 65 | _o_MACRO21 := !_o_MACRO11 | !_o_MACRO19; 66 | _o_MACRO20 := !turn_a_0 & _o_MACRO21; 67 | _o_MACRO22 := !save | saved; 68 | _o_MACRO23 := save | saved; 69 | _o_MACRO25 := fork2_o_owner_a_1 | fork2_o_owner_a_0; 70 | _o_MACRO24 := !phil1_o_state_a_0 | _o_MACRO25; 71 | _o_MACRO29 := fork2_o_owner_a_0 <-> _o_MACRO7; 72 | _o_MACRO30 := fork2_o_owner_a_1 <-> !_o_MACRO0; 73 | _o_MACRO28 := _o_MACRO29 | _o_MACRO30; 74 | _o_MACRO27 := phil1_o_state_a_0 | _o_MACRO28; 75 | _o_MACRO26 := !_o_MACRO24 | _o_MACRO27; 76 | _o_MACRO31 := !_o_MACRO24 | !_o_MACRO27; 77 | _o_MACRO32 := !fork2_o_try___to___take___left | turn_a_0; 78 | _o_MACRO33 := !phil2_o_state_a_0 | _o_MACRO25; 79 | _o_MACRO35 := phil2_o_state_a_0 | _o_MACRO28; 80 | _o_MACRO34 := !_o_MACRO33 | _o_MACRO35; 81 | _o_MACRO36 := !_o_MACRO33 | !_o_MACRO35; 82 | _o_MACRO38 := fork2_o_try___to___take___left & !_o_MACRO0; 83 | _o_MACRO39 := !fork2_o_try___to___take___right | !turn_a_0; 84 | _o_MACRO37 := _o_MACRO38 | _o_MACRO39; 85 | _o_MACRO41 := !_o_MACRO32 | !_o_MACRO39; 86 | _o_MACRO40 := !turn_a_1 & _o_MACRO41; 87 | _o_MACRO43 := fork3_o_owner_a_1 | fork3_o_owner_a_0; 88 | _o_MACRO42 := !phil2_o_state_a_0 | _o_MACRO43; 89 | _o_MACRO47 := fork3_o_owner_a_0 <-> _o_MACRO7; 90 | _o_MACRO48 := fork3_o_owner_a_1 <-> !_o_MACRO0; 91 | _o_MACRO46 := _o_MACRO47 | _o_MACRO48; 92 | _o_MACRO45 := phil2_o_state_a_0 | _o_MACRO46; 93 | _o_MACRO44 := !_o_MACRO42 | _o_MACRO45; 94 | _o_MACRO49 := !_o_MACRO42 | !_o_MACRO45; 95 | _o_MACRO50 := !fork3_o_try___to___take___left | !_o_MACRO8; 96 | _o_MACRO51 := !phil3_o_state_a_0 | _o_MACRO43; 97 | _o_MACRO53 := phil3_o_state_a_0 | _o_MACRO46; 98 | _o_MACRO52 := !_o_MACRO51 | _o_MACRO53; 99 | _o_MACRO54 := !_o_MACRO51 | !_o_MACRO53; 100 | _o_MACRO56 := !fork3_o_try___to___take___right | !_o_MACRO18; 101 | _o_MACRO55 := !_o_MACRO50 | _o_MACRO56; 102 | _o_MACRO57 := !_o_MACRO50 | !_o_MACRO56; 103 | ASSIGN 104 | init(fork1_o_owner_a_1) := FALSE; 105 | init(fork1_o_owner_a_0) := FALSE; 106 | next(fork1_o_owner_a_1) := (turn_a_0 | ((_o_MACRO0 | _o_MACRO1) & _o_MACRO3 & (fork1_o_owner_a_1 | _o_MACRO10) | _o_MACRO11) & ((_o_MACRO0 | _o_MACRO12) & _o_MACRO13 & (fork1_o_owner_a_1 | _o_MACRO15) | _o_MACRO16)) & (fork1_o_owner_a_1 | _o_MACRO20); 107 | next(fork1_o_owner_a_0) := (turn_a_0 | (_o_MACRO11 | _o_MACRO3 & (!_o_MACRO7 | _o_MACRO1) & (fork1_o_owner_a_0 | _o_MACRO10)) & (_o_MACRO16 | _o_MACRO13 & (!_o_MACRO7 | _o_MACRO12) & (fork1_o_owner_a_0 | _o_MACRO15))) & (fork1_o_owner_a_0 | _o_MACRO20); 108 | init(fork1_o_loop_a_1) := FALSE; 109 | init(fork1_o_loop_a_0) := FALSE; 110 | next(fork1_o_loop_a_1) := (fork1_o_owner_a_1 | _o_MACRO22) & (fork1_o_loop_a_1 | !_o_MACRO22); 111 | next(fork1_o_loop_a_0) := (fork1_o_owner_a_0 | _o_MACRO22) & (fork1_o_loop_a_0 | !_o_MACRO22); 112 | init(phil1_o_state_a_0) := TRUE; 113 | next(phil1_o_state_a_0) := (!phil1_o_state_a_0 | _o_MACRO0 | fork1_o_owner_a_1 | !fork1_o_owner_a_0 | fork2_o_owner_a_1 | !fork2_o_owner_a_0) & (phil1_o_state_a_0 | !phil1_o_state_a_0 & !_o_MACRO0); 114 | init(phil1_o_loop_a_0) := TRUE; 115 | next(phil1_o_loop_a_0) := (phil1_o_state_a_0 | _o_MACRO22) & (phil1_o_loop_a_0 | !_o_MACRO22); 116 | init(phil1_o_fair) := FALSE; 117 | next(phil1_o_fair) := phil1_o_fair | !_o_MACRO0 & _o_MACRO23; 118 | init(fork2_o_owner_a_1) := FALSE; 119 | init(fork2_o_owner_a_0) := FALSE; 120 | next(fork2_o_owner_a_1) := (turn_a_1 | ((_o_MACRO0 | _o_MACRO24) & _o_MACRO26 & (fork2_o_owner_a_1 | _o_MACRO31) | _o_MACRO32) & ((_o_MACRO0 | _o_MACRO33) & _o_MACRO34 & (fork2_o_owner_a_1 | _o_MACRO36) | _o_MACRO37)) & (fork2_o_owner_a_1 | _o_MACRO40); 121 | next(fork2_o_owner_a_0) := (turn_a_1 | (_o_MACRO32 | _o_MACRO26 & (!_o_MACRO7 | _o_MACRO24) & (fork2_o_owner_a_0 | _o_MACRO31)) & (_o_MACRO37 | _o_MACRO34 & (!_o_MACRO7 | _o_MACRO33) & (fork2_o_owner_a_0 | _o_MACRO36))) & (fork2_o_owner_a_0 | _o_MACRO40); 122 | init(fork2_o_loop_a_1) := FALSE; 123 | init(fork2_o_loop_a_0) := FALSE; 124 | next(fork2_o_loop_a_1) := (fork2_o_owner_a_1 | _o_MACRO22) & (fork2_o_loop_a_1 | !_o_MACRO22); 125 | next(fork2_o_loop_a_0) := (fork2_o_owner_a_0 | _o_MACRO22) & (fork2_o_loop_a_0 | !_o_MACRO22); 126 | init(phil2_o_state_a_0) := TRUE; 127 | next(phil2_o_state_a_0) := (!phil2_o_state_a_0 | !_o_MACRO8 | !fork2_o_owner_a_1 | fork2_o_owner_a_0 | !fork3_o_owner_a_1 | fork3_o_owner_a_0) & (phil2_o_state_a_0 | !phil2_o_state_a_0 & _o_MACRO8); 128 | init(phil2_o_loop_a_0) := TRUE; 129 | next(phil2_o_loop_a_0) := (phil2_o_state_a_0 | _o_MACRO22) & (phil2_o_loop_a_0 | !_o_MACRO22); 130 | init(phil2_o_fair) := FALSE; 131 | next(phil2_o_fair) := phil2_o_fair | _o_MACRO8 & _o_MACRO23; 132 | init(fork3_o_owner_a_1) := FALSE; 133 | init(fork3_o_owner_a_0) := FALSE; 134 | next(fork3_o_owner_a_1) := ((_o_MACRO0 | _o_MACRO42) & _o_MACRO44 & (fork3_o_owner_a_1 | _o_MACRO49) | _o_MACRO50) & ((_o_MACRO0 | _o_MACRO51) & _o_MACRO52 & (fork3_o_owner_a_1 | _o_MACRO54) | _o_MACRO55) & (fork3_o_owner_a_1 | _o_MACRO57); 135 | next(fork3_o_owner_a_0) := (_o_MACRO50 | _o_MACRO44 & (!_o_MACRO7 | _o_MACRO42) & (fork3_o_owner_a_0 | _o_MACRO49)) & (_o_MACRO55 | _o_MACRO52 & (!_o_MACRO7 | _o_MACRO51) & (fork3_o_owner_a_0 | _o_MACRO54)) & (fork3_o_owner_a_0 | _o_MACRO57); 136 | init(fork3_o_loop_a_1) := FALSE; 137 | init(fork3_o_loop_a_0) := FALSE; 138 | next(fork3_o_loop_a_1) := (fork3_o_owner_a_1 | _o_MACRO22) & (fork3_o_loop_a_1 | !_o_MACRO22); 139 | next(fork3_o_loop_a_0) := (fork3_o_owner_a_0 | _o_MACRO22) & (fork3_o_loop_a_0 | !_o_MACRO22); 140 | init(phil3_o_state_a_0) := TRUE; 141 | next(phil3_o_state_a_0) := (!phil3_o_state_a_0 | !_o_MACRO18 | !fork3_o_owner_a_1 | !fork3_o_owner_a_0 | !fork1_o_owner_a_1 | !fork1_o_owner_a_0) & (phil3_o_state_a_0 | !phil3_o_state_a_0 & _o_MACRO18); 142 | init(phil3_o_loop_a_0) := TRUE; 143 | next(phil3_o_loop_a_0) := (phil3_o_state_a_0 | _o_MACRO22) & (phil3_o_loop_a_0 | !_o_MACRO22); 144 | init(phil3_o_fair) := FALSE; 145 | next(phil3_o_fair) := phil3_o_fair | _o_MACRO18 & _o_MACRO23; 146 | init(saved) := FALSE; 147 | next(saved) := _o_MACRO23; 148 | init(live) := FALSE; 149 | next(live) := found | live; 150 | INVAR 151 | !turn_a_1 | !turn_a_0 152 | SPEC 153 | AG (live | !fair | !looped) 154 | --------------------------------------------------------------------------------