#!/usr/bin/python
import sys

# This is a 1-safe P/T-net deadlock checker for ACSD06+ATPN06 tutorial demo.
# It prints out a run of a Boolean circuit from a Petri net model
# to be solved by bczchaff, bcminisat, or bcsat.
# Example:
# ./1b-pn-bmc < dp_12-step.net | bczchaff -v | ./cex-print

exec sys.stdin
#print P
#print T
#print F
#print M_0

if((semantics != "interleaving") and
   (semantics != "step") and
   (semantics != "process")):
    print "Unknown semantics: %s" % (semantics)
    sys.exit(1)

preset = {}
postset = {}

for p in P:
    preset[p] = []
    postset[p] = []
for t in T:
    preset[t] = []
    postset[t] = []
        
for arc in F:
    source = arc[0]
    dest = arc[1]
    preset[dest].append(source)
    postset[source].append(dest)

initial = {}
for p in M_0:
    initial[p] = 1

#print preset
#print postset
#print initial

j = 0

print "BC1.0"
for p in P:
    if(initial.has_key(p)):
        print "%s_0 := T;" % (p)
    else:
        print "%s_0 := F;" % (p)

for i in range(0,bound+1):

#   Encoding of place updates
    
    for p in P:
        trans = ""
        trans = trans + "%s_%d := " % (p,(i+1))
        
        preset_list = ""
	preset_size = 0
        for t in preset[p]:
            preset_list = preset_list + "%s_%i, " % (t,i)
	    preset_size = preset_size + 1
        if preset_list != "":
            preset_list = preset_list[:-2]
        else:
            preset_list = "F"

        postset_list = ""
	postset_size = 0
        for t in postset[p]:
            postset_list = postset_list + "%s_%i, " % (t,i)
	    postset_size = postset_size + 1
        if postset_list != "":
            postset_list = postset_list[:-2]
        else:
            postset_list = "F"

#       Remove conflicts wrt. p in step and process semantics

	if(((semantics == "step") or (semantics == "process")) and (postset_size > 1)):
	    if(i < bound):
		print "nc%s_%d := [0,1](%s);" % (p,i,postset_list)
		print "ASSIGN nc%s_%d;" % (p,i)

#       Add the token updating

        if(postset_size == 1):
	    postset_list = "AND(%s_%d, NOT(%s))" % (p,i,postset_list)
	else:
	    postset_list = "AND(%s_%d, NOT(OR(%s)))" % (p,i,postset_list)

	if(preset_size >= 1):
	    if(preset_size == 1):	
		if(i < bound):
		    print "g%s_%d := %s;" % (p,(i+1),preset_list)
	    else:
		if(i < bound):
		    print "g%s_%d := OR(%s);" % (p,(i+1),preset_list)
	    preset_list = "g%s_%d" % (p,(i+1))

        trans = trans + "OR(%s, %s)" % (preset_list, postset_list)
        trans = trans + ";"

        if(i < bound):
            print trans

#   Encoding of transition enabling and deadlock predicate

    live_list = "live_%d := OR(" % (i)

    for t in T:

        preset_list = ""
        gpreset_list = ""
	preset_size = 0
        for p in preset[t]:
            preset_list = preset_list + "%s_%i, " % (p,i)
            gpreset_list = gpreset_list + "g%s_%i, " % (p,i)
	    preset_size = preset_size + 1
        if preset_list != "":
            preset_list = preset_list[:-2]
            gpreset_list = gpreset_list[:-2]
        else:
            preset_list = "T"
            gpreset_list = "T"

#       Add the process constraints
	if((i > 0) and (semantics == "process")):
	    if(preset_size == 1):
		trans = "gate%d := OR(NOT(%s_%d), AND(" % (j,t,i)
		trans = trans + "%s, %s));" % (preset_list, gpreset_list)
	    else:
		trans = "gate%d := OR(NOT(%s_%d), AND(" % (j,t,i)
		trans = trans + "%s, OR(%s)));" % (preset_list, gpreset_list)
	else:
	    if(preset_size == 1):
		trans = "gate%d := OR(NOT(%s_%d), " % (j,t,i)
		trans = trans + "%s);" % (preset_list)
	    else:
		trans = "gate%d := OR(NOT(%s_%d), AND(" % (j,t,i)
		trans = trans + "%s));" % (preset_list)
	    
	if(preset_size == 1):
	    live_list = live_list + "%s, " % (preset_list)
	else:
	    live_list = live_list + "AND(%s), " % (preset_list)


        if(i < bound):
            print trans
            print "ASSIGN gate%d;" % (j)
            j = j+1

# Removal of conflicts for interleaving

    if ((i < bound) and (semantics == "interleaving")):
        rc = "rc%d := [0,1](" % (i)
	for t1 in T:
	    rc = rc + "%s_%d, " % (t1,i)
        rc = rc[:-2] + ");"
        print rc
	print "ASSIGN rc%d;" % (i)

# Idling removal, deactivated

    if ((0 == 1) and (i < bound)):
        idle_list = "idle_%d := NOT(OR(" % (i)
        for t in T:
            idle_list = idle_list + "%s_%d, " % (t,i)
        idle_list = idle_list[:-2] + "));"
        print idle_list
        print "ASSIGN ~idle_%d;" % (i)

    live_list = live_list[:-2] + ");"

#   Print liveness requirement only for the final state

    if(i == bound):
	print live_list
	print "ASSIGN ~live_%i;" % (bound)
