# abctcl sample program



# include abctcl.tcl script
source abctcl.tcl



# compares several resynthesis commands
# calls each given command several times until number of ANDs stops differing
# prints name, number of ANDs and number of iterations for command with best
# result - minimal number of ANDs
proc compareResyn {} {
	# data file name
	#set filename {examples/apex4.pla}
	set filename {examples/pj1.blif}

	# some resynthesis commands may take longer time to execute
	# timeout variable is defined on global level
	global timeout
	set timeout 60


	# start value - +infinity
	set startBestAND 1000000
	# best and value from all synthesis commands
	set globalBestAND $startBestAND
	# name of best synthesis command
	set globalBestSynt "not available"
	# in how many iterations was value of globalBestAND reached
	set globalBestRunsNeeded -1

	# resynthesis commands to compare
	set resynNames {"resyn; resyn2" "resyn2" "resyn" "resyn2a" "resyn3"}

	foreach resynName $resynNames {
		puts -nonewline "\nread: "

		# read data
		abc_read readRes $filename
		if {$readRes(success) == 1} {
			puts "ok"
		} else {
			puts "failed"
			parray readRes
			puts "quitting"
			return -1
		}

		puts [format "'%s'" $resynName]
		puts [format "globalBestAND: %d, globalBestSynt: '%s', globalBestRunsNeeded: %d" $globalBestAND $globalBestSynt $globalBestRunsNeeded]

		set bestSynt $resynName
		# local best number of ands
		set bestAND $startBestAND

		set oldBestAND [expr $bestAND + 1]
		set runsNeeded 0

		# loop with one command
		while {$oldBestAND > $bestAND} {
			set oldBestAND $bestAND

			incr runsNeeded

			# call synthesis command
			abcAnyCommand $resynName anyCommandResult
			if {$anyCommandResult(success) != 1} {
				puts [format "calling '%s' failed" $resynName]
				parray anyCommandResult
				puts "quitting"
				return -1
			}

			# call print_stats
			abc_print_stats print_statsResult
			if {$print_statsResult(success) != 1} {
				puts "calling 'print_stats' failed"
				parray print_statsResult
				puts "quitting"
				return -1
			}

			# use only 'and' field from output
			set bestAND $print_statsResult(and)
			if {$bestAND < $globalBestAND} {
				set globalBestAND $bestAND
				set globalBestSynt $resynName
				set globalBestRunsNeeded $runsNeeded
			}

			puts [format "localBestAND: %d, globalBestAND: %d, globalBestSynt: '%s', globalBestRunsNeeded: %d" $bestAND $globalBestAND $globalBestSynt $globalBestRunsNeeded]
		}	
	}
	
	puts "done"
	puts [format "globalBestAND: %d" $globalBestAND]
	puts [format "globalBestSynt: %s" $globalBestSynt]
	puts [format "globalBestRunsNeeded: %s" $globalBestRunsNeeded]

	return 1
}



# ---- main

puts ".start"

# init
puts -nonewline "abcInit ... "
set result [abcInit res]
if {$result == 1} {
	puts "ok"
} else {
	puts "failed, quitting"
	parray res
	exit -1
}
array unset res



compareResyn



abcDone

puts ".done"

