Generators: cleanup

This commit is contained in:
2026-04-10 17:52:22 +01:00
parent 554b34afcf
commit f319d09ad7
11 changed files with 421 additions and 538 deletions

View File

@@ -0,0 +1,103 @@
#!/usr/bin/env python3
"""
Generator for the Assembly-line (ASM) benchmark.
Produces a distributed reaction system modelling an assembly line
where N sequential processes pass activation tokens. Each process
cycles through entities a -> y,b -> c -> d, and the final process
signals 'done'. Uses a context automaton for scheduling.
"""
import argparse
OPTIONS = "options { use-context-automaton; make-progressive; };\n"
PROC_TEMPLATE = """
proc{i} {{
{{{{a}}, {{s}} -> {{y}}}};
{{{{y}}, {{s}} -> {{y}}}};
{{{{a}}, {{s}} -> {{b}}}};
{{{{b}}, {{s}} -> {{c}}}};
{{{{c}}, {{s}} -> {{d}}}};
{{{{d,y}}, {{s}} -> {{dy}}}};
}};
"""
FINAL_PROC = """
procFinal {
{{done}, {s} -> {done}};
};
"""
CA_TEMPLATE = """
context-automaton {{
states {{ init, act }};
init-state {{ init }};
transitions {{
{transitions}
}};
}};
"""
PROPERTY_TEMPLATE = '\nrsctlk-property {{ {name} : {formula} }};\n'
def generate(n):
out = OPTIONS
out += "\nreactions {\n"
for i in range(1, n + 1):
out += PROC_TEMPLATE.format(i=i)
out += FINAL_PROC
out += "};\n"
indent = 8 * " "
transitions = ""
# init -> act: first process gets activated
transitions += "{indent}{{ proc1={{a}} }}: init -> act;\n".format(indent=indent)
# act -> act: process stays idle (dy not produced)
for i in range(1, n + 1):
transitions += "{indent}{{ proc{i}={{}} }}: act -> act : ~proc{i}.dy;\n".format(
indent=indent, i=i)
# act -> act: next process gets activated when previous produces 'dy'
for i in range(2, n + 1):
transitions += "{indent}{{ proc{i}={{a}} }}: act -> act : proc{prev}.dy;\n".format(
indent=indent, i=i, prev=i - 1)
# act -> act: final process signals done when all have produced 'dy'
all_dy = " AND ".join("proc{}.dy".format(i) for i in range(1, n + 1))
transitions += "{indent}{{ procFinal={{done}} }}: act -> act : {guard};\n".format(
indent=indent, guard=all_dy)
out += CA_TEMPLATE.format(transitions=transitions)
# f1: the assembly line eventually completes
out += PROPERTY_TEMPLATE.format(name="f1", formula="EF( procFinal.done )")
# f2: last process knows its predecessor has produced 'y'
f2 = "AG( proc{n}.d IMPLIES K[proc{n}]( proc{prev}.y ) )".format(n=n, prev=n - 1)
out += PROPERTY_TEMPLATE.format(name="f2", formula=f2)
# x1: negation of f1 (sanity check -- should also hold)
out += PROPERTY_TEMPLATE.format(name="x1", formula="EF( ~procFinal.done )")
return out
def main():
parser = argparse.ArgumentParser(description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument("n", type=int, help="number of processes (must be > 1)")
args = parser.parse_args()
if args.n < 2:
parser.error("number of processes must be > 1")
print(generate(args.n))
if __name__ == "__main__":
main()

View File

@@ -1,6 +1,15 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""
Generator for the DRS (Distributed Reaction Systems) epistemic benchmark.
Produces a distributed reaction system with epistemic properties
(knowledge operators). The system models signal transduction cascades
with configurable depth (x), number of components (y), threshold (z),
and context automaton variant (a or b).
"""
import sys import sys
import argparse
import itertools import itertools
@@ -272,18 +281,20 @@ class DRSGenerator:
def main(): def main():
if len(sys.argv) < 1 + 4: parser = argparse.ArgumentParser(description=__doc__,
print(f"Usage: {sys.argv[0]} <x> <y> <z> <Aut>") formatter_class=argparse.RawDescriptionHelpFormatter)
print("\twhere x,y,z >= 2 and y >= z") parser.add_argument("x", type=int, help="cascade depth (>= 2)")
print("\tAut: a, b") parser.add_argument("y", type=int, help="number of components (>= 2, >= z)")
sys.exit(1) parser.add_argument("z", type=int, help="threshold (>= 2, <= y)")
parser.add_argument("aut", choices=["a", "b"], help="automaton variant")
args = parser.parse_args()
g = DRSGenerator( if args.x < 2 or args.y < 2 or args.z < 2:
x=int(sys.argv[1]), parser.error("x, y, z must all be >= 2")
y=int(sys.argv[2]), if args.y < args.z:
z=int(sys.argv[3]), parser.error("y must be >= z")
aut=sys.argv[4],
) DRSGenerator(x=args.x, y=args.y, z=args.z, aut=args.aut)
if __name__ == "__main__": if __name__ == "__main__":

View File

@@ -1,13 +1,20 @@
#!/usr/bin/env python #!/usr/bin/env python3
"""
Generator for the Traffic Guard Controller (TGC) benchmark.
from sys import argv,exit Produces a distributed reaction system where N processes compete
for access to a shared resource, governed by a context automaton
OPTIONS_STR = """ with green/red states. Generates RSCTLK properties for liveness,
options { use-context-automaton; make-progressive; }; reachability, and mutual exclusion (epistemic).
""" """
PROC_STR = """ import argparse
proc{:d} {{
OPTIONS = "options { use-context-automaton; make-progressive; };\n"
PROC_TEMPLATE = """
proc{i} {{
{{{{out}}, {{}} -> {{approach}}}}; {{{{out}}, {{}} -> {{approach}}}};
{{{{approach}}, {{req}} -> {{req}}}}; {{{{approach}}, {{req}} -> {{req}}}};
{{{{allowed}}, {{}} -> {{in}}}}; {{{{allowed}}, {{}} -> {{in}}}};
@@ -16,102 +23,94 @@ PROC_STR = """
}}; }};
""" """
CA_STR = """ CA_TEMPLATE = """
context-automaton {{ context-automaton {{
states {{ init, green, red }}; states {{ init, green, red }};
init-state {{ init }}; init-state {{ init }};
transitions {{ transitions {{
{:s} {transitions}
}}; }};
}}; }};
""" """
PROPERTY_STR = """ PROPERTY_TEMPLATE = '\nrsctlk-property {{ {name} : {formula} }};\n'
rsctlk-property {{ {:s} : {:s} }};
"""
################################################################# def conj(fmt, indices, sep=" AND "):
return sep.join(fmt.format(i=i) for i in indices)
if len(argv) < 1:
print("Usage: {:s} <number of processes>".format(argv[0]))
exit(100)
n = int(argv[1]) def generate(n):
out = OPTIONS
out += "\nreactions {\n"
for i in range(n):
out += PROC_TEMPLATE.format(i=i)
out += "};\n"
assert n > 1, "number of proc must be > 1" indent = 8 * " "
transitions = ""
out = "" # init -> green: all processes start with 'out'
transitions += indent + "{ "
transitions += " ".join("proc{:d}={{out}}".format(i) for i in range(n))
transitions += " }: init -> green;\n"
out += OPTIONS_STR # green -> red: a process requests
out += "reactions {\n" for i in range(n):
for i in range(n): transitions += "{indent}{{ proc{i}={{allowed}} }}: green -> red : proc{i}.req;\n".format(
out += PROC_STR.format(i) indent=indent, i=i)
out += "};\n"
transitions = "" # green -> green: no requests pending
no_req = conj("~proc{i}.req", range(n))
for i in range(n):
transitions += "{indent}{{ proc{i}={{}} }}: green -> green : {guard};\n".format(
indent=indent, i=i, guard=no_req)
init_trans = 8*" " + "{ " # red -> green: a process leaves
for i in range(n): for i in range(n):
init_trans += "proc{:d}={{out}} ".format(i) transitions += "{indent}{{ proc{i}={{}} }}: red -> green : proc{i}.leave;\n".format(
init_trans += "}: init -> green;\n" indent=indent, i=i)
transitions += init_trans
for i in range(n): # red -> red: no process leaves
transitions += "{:s}{{ proc{:d}={{allowed}} }}: green -> red : proc{:d}.req;\n".format(8*" ", i, i) no_leave = conj("~proc{i}.leave", range(n))
for i in range(n):
transitions += "{indent}{{ proc{i}={{}} }}: red -> red : {guard};\n".format(
indent=indent, i=i, guard=no_leave)
no_req_cond = "~proc0.req" out += CA_TEMPLATE.format(transitions=transitions)
for i in range(1, n):
no_req_cond += " AND ~proc{:d}.req".format(i)
for i in range(n): # f1: each process can eventually enter
transitions += "{:s}{{ proc{:d}={{}} }}: green -> green : {:s};\n".format(8*" ", i, no_req_cond) f1 = conj("EF( E<proc{i}.allowed>X( proc{i}.in ) )", range(n))
out += PROPERTY_TEMPLATE.format(name="f1", formula=f1)
for i in range(n): # f2: all processes can simultaneously approach
transitions += "{:s}{{ proc{:d}={{}} }}: red -> green : proc{:d}.leave;\n".format(8*" ", i, i) f2 = "EF( " + conj("proc{i}.approach", range(n)) + " )"
out += PROPERTY_TEMPLATE.format(name="f2", formula=f2)
no_leave_cond = "~proc0.leave" # f3: mutual exclusion (knowledge)
for i in range(1, n): others_not_in = conj("~proc{i}.in", range(1, n))
no_leave_cond += " AND ~proc{:d}.leave".format(i) f3 = "AG( proc0.in IMPLIES K[proc0]({}) )".format(others_not_in)
out += PROPERTY_TEMPLATE.format(name="f3", formula=f3)
for i in range(n): # f4: mutual exclusion (common knowledge)
transitions += "{:s}{{ proc{:d}={{}} }}: red -> red : {:s};\n".format(8*" ", i, no_leave_cond) all_agents = conj("proc{i}", range(n), sep=",")
f4 = "AG( proc0.in IMPLIES C[{}]({}) )".format(all_agents, others_not_in)
out += PROPERTY_TEMPLATE.format(name="f4", formula=f4)
out += CA_STR.format(transitions) return out
## f1
#formula = "EF( proc0.in )"
#out += PROPERTY_STR.format("f1",formula)
# f1 def main():
formula = "EF( E<proc0.allowed>X( proc0.in ) )" parser = argparse.ArgumentParser(description=__doc__,
for i in range(1, n): formatter_class=argparse.RawDescriptionHelpFormatter)
formula += " AND EF( E<proc{:d}.allowed>X( proc{:d}.in ) )".format(i, i) parser.add_argument("n", type=int, help="number of processes (must be > 1)")
out += PROPERTY_STR.format("f1",formula) args = parser.parse_args()
# f2 if args.n < 2:
formula = "EF( proc0.approach" parser.error("number of processes must be > 1")
for i in range(1, n):
formula += " AND proc{:d}.approach".format(i)
formula += " )"
out += PROPERTY_STR.format("f2",formula)
# f3 print(generate(args.n))
subf = "~proc1.in"
for i in range(2, n):
subf += " AND ~proc{:d}.in".format(i)
formula = "AG( proc0.in IMPLIES K[proc0]({:s}) )".format(subf)
out += PROPERTY_STR.format("f3",formula)
# f4
subf = "~proc1.in"
for i in range(2, n):
subf += " AND ~proc{:d}.in".format(i)
all_agents = "proc0"
for i in range(1, n):
all_agents += ",proc{:d}".format(i)
formula = "AG( proc0.in IMPLIES C[{:s}]({:s}) )".format(all_agents,subf)
out += PROPERTY_STR.format("f4",formula)
print(out)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,62 @@
#!/usr/bin/env python3
"""
Generator for the Abstract Pipeline benchmark.
Produces a reaction system modelling a pipeline of N modules,
each cycling through entities a -> y,b -> c -> d before passing
activation to the next module. The final reaction requires all
modules to have completed (all y_i present).
NOTE: generates old-syntax input (context-entities, initial-contexts,
rsctl-property) which is not compatible with the current parser.
"""
import argparse
def generate(n, variant):
out = "reactions {\n"
out += "\t{ {x},{s} -> {a1} };\n"
for i in range(1, n + 1):
out += "\t{{ {{a{i}}},{{s}} -> {{y{i}}} }};\n".format(i=i)
out += "\t{{ {{a{i}}},{{s}} -> {{b{i}}} }};\n".format(i=i)
out += "\t{{ {{b{i}}},{{s}} -> {{c{i}}} }};\n".format(i=i)
out += "\t{{ {{c{i}}},{{s}} -> {{d{i}}} }};\n".format(i=i)
out += "\t{{ {{d{i},y{i}}},{{s}} -> {{a{j}}} }};\n".format(i=i, j=i + 1)
out += "\t{{ {{y{i}}},{{s}} -> {{y{i}}} }};\n".format(i=i)
final_reactants = "a" + str(n + 1)
for i in range(1, n + 1):
final_reactants += ",y" + str(i)
out += "\t{{ {{{r}}},{{s}} -> {{r}} }};\n".format(r=final_reactants)
out += "}\n"
if variant == 1:
out += "context-entities { s }\n"
elif variant == 2:
ctx = "s"
for i in range(1, n + 1):
if i % 2 == 0:
ctx += ",a" + str(i)
out += "context-entities {{ {} }}\n".format(ctx)
out += "initial-contexts { {x} }\n"
out += "rsctl-property { E[{}]F(r) }\n"
return out
def main():
parser = argparse.ArgumentParser(description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument("n", type=int, help="number of pipeline modules")
parser.add_argument("variant", type=int, choices=[1, 2],
help="context variant (1: minimal, 2: extended)")
args = parser.parse_args()
print(generate(args.n, args.variant))
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,88 @@
#!/usr/bin/env python3
"""
Generator for the Binary Counter (BC) benchmark.
Produces a reaction system modelling an N-bit binary counter
with increment and decrement operations controlled via context
entities. Generates one of four RSCTL properties.
NOTE: generates old-syntax input (context-entities, initial-contexts,
rsctl-property) which is not compatible with the current parser.
"""
import argparse
K = 8 # constant used by property 3
def generate(n, prop):
out = "reactions {\n"
# (1) no dec, no inc: bits persist
out += "\t# (1) no decrement, no increment\n"
for j in range(n):
out += "\t{{{{p{j}}},{{dec,inc}} -> {{p{j}}}}};\n".format(j=j)
# (2) increment operation
out += "\n\t# (2) increment operation\n"
out += "\t{{inc},{dec,p0} -> {p0}};\n"
for j in range(1, n):
bits = ",".join("p" + str(k) for k in range(j))
out += "\t{{{{inc,{bits}}},{{dec,p{j}}} -> {{p{j}}}}};\n".format(bits=bits, j=j)
out += "\n\t# the more significant bits remain (inc)\n"
for j in range(n):
for k in range(j + 1, n):
out += "\t{{{{inc,p{k}}},{{dec,p{j}}} -> {{p{k}}}}};\n".format(j=j, k=k)
# (3) decrement operation
out += "\n\t# (3) decrement operation\n"
for j in range(n):
bits = ",".join("p" + str(k) for k in range(j + 1))
out += "\t{{{{dec}},{{inc,{bits}}} -> {{p{j}}}}};\n".format(bits=bits, j=j)
out += "\n\t# the more significant bits remain (dec)\n"
for j in range(n):
for k in range(j + 1, n):
out += "\t{{{{dec,p{j},p{k}}},{{inc}} -> {{p{k}}}}};\n".format(j=j, k=k)
out += "}\n\n"
out += "context-entities { inc,dec }\n"
out += "initial-contexts { {} }\n"
if prop == 1:
all_neg = " AND ".join("~p" + str(i) for i in range(n))
all_pos = " AND ".join("p" + str(i) for i in range(n))
out += "rsctl-property {{ AG(({}) IMPLIES E[{{inc}},{{dec}}]F({})) }}\n".format(
all_neg, all_pos)
elif prop == 2:
all_pos = " AND ".join("p" + str(i) for i in range(n))
all_neg = " AND ".join("~p" + str(i) for i in range(n))
out += "rsctl-property {{ AG(({}) IMPLIES A[{{inc}}]X({})) }}\n".format(
all_pos, all_neg)
elif prop == 3:
parts = ["p" + str(i) for i in range(n - K)]
parts += ["~p" + str(i) for i in range(n - K, n)]
out += "rsctl-property {{ E[{{inc}}]F({}) }}\n".format(" AND ".join(parts))
elif prop == 4:
out += "rsctl-property {{ AG( p{} IMPLIES EF ~p{} ) }}\n".format(n - 1, n - 1)
return out
def main():
parser = argparse.ArgumentParser(description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument("n", type=int, help="number of bits")
parser.add_argument("property", type=int, choices=[1, 2, 3, 4],
help="property to generate (1-4)")
args = parser.parse_args()
if args.property == 3 and args.n < K + 1:
parser.error("n must be >= {} for property 3".format(K + 1))
print(generate(args.n, args.property))
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,71 @@
#!/usr/bin/env python3
"""
Generator for the Mutual Exclusion (Mutex) benchmark.
Produces a reaction system modelling N processes competing for
exclusive access to a critical section, using activation signals,
request tokens, and a lock. Generates one of three RSCTL properties.
NOTE: generates old-syntax input (context-entities, initial-contexts,
rsctl-property) which is not compatible with the current parser.
"""
import argparse
def generate(n, formula):
out = "reactions {\n"
for i in range(n):
out += "\t{{{{out{i},act{i}}},{{}} -> {{request{i}}}}};\n".format(i=i)
out += "\t{{{{out{i}}},{{act{i}}} -> {{out{i}}}}};\n".format(i=i)
for j in range(n):
if i != j:
out += "\t{{{{request{i},act{i},act{j}}},{{}} -> {{request{i}}}}};\n".format(
i=i, j=j)
out += "\t{{{{request{i}}},{{act{i}}} -> {{request{i}}}}};\n".format(i=i)
other_acts = ",".join("act" + str(j) for j in range(n) if i != j)
out += "\t{{{{request{i},act{i}}},{{{others},lock}} -> {{in{i},lock}}}};\n".format(
i=i, others=other_acts)
out += "\t{{{{in{i},act{i}}},{{}} -> {{out{i},done}}}};\n".format(i=i)
out += "\t{{{{in{i}}},{{act{i}}} -> {{in{i}}}}};\n".format(i=i)
out += "\t{{lock},{done} -> {lock}};\n"
out += "}\n"
ctx_ents = ",".join("act" + str(i) for i in range(n))
out += "context-entities {{ {} }}\n".format(ctx_ents)
init_ents = ",".join("out" + str(i) for i in range(n))
out += "initial-contexts {{ {{{}}} }}\n".format(init_ents)
if formula == 1:
out += "rsctl-property { A[{act1}]F(in1) }\n"
elif formula == 2:
out += "rsctl-property { E[{act1}]F(in1) }\n"
elif formula == 3:
pairs = []
for i in range(n):
for j in range(i + 1, n):
pairs.append("~(in{} AND in{})".format(i, j))
out += "rsctl-property {{ AG({}) }}\n".format(" AND ".join(pairs))
return out
def main():
parser = argparse.ArgumentParser(description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument("n", type=int, help="number of processes")
parser.add_argument("formula", type=int, choices=[1, 2, 3],
help="formula to generate (1: A[]F, 2: E[]F, 3: AG mutex)")
args = parser.parse_args()
print(generate(args.n, args.formula))
if __name__ == "__main__":
main()

View File

@@ -1,47 +0,0 @@
#!/usr/bin/env python
from sys import argv,exit
if len(argv) < 3:
print "Usage:", argv[0], "<number of modules> <variant>"
exit(100)
n = int(argv[1])
v = int(argv[2])
if not ( v > 0 and v < 3 ):
print "unsupported variant"
exit(100)
print "reactions {"
s = "\t{ {x},{s} -> {a1} };\n"
print s
for i in range(1,n+1):
s = "\t{ {a" + str(i) + "},{s} -> {y" + str(i) + "} };\n"
s += "\t{ {a" + str(i) + "},{s} -> {b" + str(i) + "} };\n"
s += "\t{ {b" + str(i) + "},{s} -> {c" + str(i) + "} };\n"
s += "\t{ {c" + str(i) + "},{s} -> {d" + str(i) + "} };\n"
s += "\t{ {d" + str(i) + ",y" + str(i) + "},{s} -> {a" + str(i+1) + "} };\n"
s += "\t{ {y" + str(i) + "},{s} -> {y" + str(i) + "} };\n"
print s
s = "\t{ {a" + str(n+1)
for i in range(1,n+1):
s += ",y" + str(i)
s += "},{s} -> {r} };\n"
print s
print "}"
if v == 1:
print "context-entities { s }"
elif v == 2:
s = "context-entities { s"
for i in range(1,n+1):
if i % 2 == 0:
s += ",a" + str(i)
s += " }"
print s
print "initial-contexts { {x} }"
print "rsctl-property { E[{}]F(r) }"

View File

@@ -1,93 +0,0 @@
#!/usr/bin/env python
from sys import argv,exit
OPTIONS_STR = """
options { use-context-automaton; make-progressive; };
"""
PROC_STR = """
proc{:d} {{
{{{{a}}, {{s}} -> {{y}}}};
{{{{y}}, {{s}} -> {{y}}}};
{{{{a}}, {{s}} -> {{b}}}};
{{{{b}}, {{s}} -> {{c}}}};
{{{{c}}, {{s}} -> {{d}}}};
{{{{d,y}}, {{s}} -> {{dy}}}};
}};
"""
FINAL_PROC = """
procFinal {
{{done}, {s} -> {done}};
};
"""
CA_STR = """
context-automaton {{
states {{ init, act }};
init-state {{ init }};
transitions {{
{:s}
}};
}};
"""
PROPERTY_STR = """
rsctlk-property {{ {:s} : {:s} }};
"""
#################################################################
if len(argv) < 1:
print("Usage: {:s} <number of processes>".format(argv[0]))
exit(100)
n = int(argv[1])
assert n > 1, "number of proc must be > 1"
out = ""
out += OPTIONS_STR
out += "reactions {\n"
for i in range(1, n+1):
out += PROC_STR.format(i)
out += FINAL_PROC
out += "};\n"
transitions = ""
init_trans = 8*" " + "{ proc1={a} }: init -> act;\n"
transitions += init_trans
for i in range(1, n+1):
transitions += "{:s}{{ proc{:d}={{}} }}: act -> act : ~proc{:d}.dy;\n".format(8*" ", i, i, i)
for i in range(2, n+1):
transitions += "{:s}{{ proc{:d}={{a}} }}: act -> act : proc{:d}.dy;\n".format(8*" ", i, i-1)
final_cond = "proc1.dy"
for i in range(2, n+1):
final_cond += " AND proc{:d}.dy".format(i)
transitions += "{:s}{{ procFinal={{done}} }}: act -> act : {:s};\n".format(8*" ", final_cond)
out += CA_STR.format(transitions)
# f1
formula = "EF( procFinal.done )"
out += PROPERTY_STR.format("f1",formula)
# f2
formula = "AG( proc{:d}.d IMPLIES K[proc{:d}]( proc{:d}.y ) )".format(n, n, n-1)
out += PROPERTY_STR.format("f2",formula)
# x1
formula = "EF( ~procFinal.done )"
out += PROPERTY_STR.format("x1",formula)
print(out)

View File

@@ -1,118 +0,0 @@
#!/usr/bin/env python2.7
from sys import argv,exit
if len(argv) < 3:
print "Usage:", argv[0], "<number of bits> <property>"
exit(100)
n = int(argv[1])
property = int(argv[2])
K = 8
if property == 3:
if n < K+1:
print "too small n"
exit(100)
if not ( property >= 1 and property < 5 ):
print "property: 1-4"
exit(101)
print "reactions {"
# (1) no dec, no inc
print "\t# (1) no decrement, no increment"
for j in range(0,n):
print "\t{{p" + str(j) + "},{dec,inc} -> {p" + str(j) + "}};"
# (2) increment
s = "\n\t# (2) increment operation\n"
s += "\t{{inc},{dec,p0} -> {p0}};\n"
for j in range(1,n):
s += "\t{{inc,"
for k in range(0,j):
s += "p" + str(k)
if k < j-1:
s += ","
s += "},{dec,p" + str(j) + "} -> {p" + str(j) + "}};\n"
print s
print "\t# the more significant bits remain (inc)"
s = ""
for j in range(0,n):
for k in range(j+1,n):
s += "\t{{inc,p" + str(k) + "},{dec,p" + str(j) + "} -> {p" + str(k) + "}};\n"
print s
print "\t# (3) decrement operation"
s = ""
for j in range(0,n):
s += "\t{{dec},{inc,"
for k in range(0,j+1):
s += "p" + str(k)
if k < j:
s += ","
s += "} -> {p" + str(j) + "}};\n"
print s
print "\t# the more significant bits remain (dec)"
s = ""
for j in range(0,n):
for k in range(j+1,n):
s += "\t{{dec,p" + str(j) + ",p" + str(k) + "},{inc} -> {p" + str(k) + "}};\n"
s += "}\n"
print s
print "context-entities { inc,dec }"
print "initial-contexts { {} }"
if property == 4:
print "rsctl-property { AG( p" + str(n-1) + " IMPLIES EF ~p" + str(n-1) + " ) }"
elif property == 1:
s = "rsctl-property { AG(("
for i in range(0,n):
s += "~p" + str(i)
if i < n-1:
s += " AND "
s += ") IMPLIES E[{inc},{dec}]F("
for i in range(0,n):
s += "p" + str(i)
if i < n-1:
s += " AND "
s += ")) }"
print s
elif property == 2:
s = "rsctl-property { AG(("
for i in range(0,n):
s += "p" + str(i)
if i < n-1:
s += " AND "
s += ") IMPLIES A[{inc}]X("
for i in range(0,n):
s += "~p" + str(i)
if i < n-1:
s += " AND "
s += ")) }"
print s
elif property == 3:
s = "rsctl-property { E[{inc}]F("
for i in range(0,n-K):
s += "p" + str(i)
if i < n-1:
s += " AND "
for i in range(n-K,n):
s += "~p" + str(i)
if i < n-1:
s += " AND "
s += ") }"
print s

View File

@@ -1,76 +0,0 @@
#!/usr/bin/env python
from sys import argv,exit
if len(argv) < 3:
print "Usage:", argv[0], "<number of processes> <formula>"
exit(100)
n = int(argv[1])
f = int(argv[2])
if not ( f>0 and f<4 ):
print "unsupported formula"
exit(100)
print "reactions {"
for i in range(0,n):
s = "\t{{out" + str(i) + ",act" + str(i) + "},{} -> {request" + str(i) + "}};\n"
s += "\t{{out" + str(i) + "},{act" + str(i) + "} -> {out" + str(i) + "}};\n"
for j in range(0,n):
if i != j:
s += "\t{{request" + str(i) + ",act" + str(i) + ",act" + str(j) + "},{} -> {request" + str(i) + "}};\n"
#s += "\t{{request" + str(i) + "},{"
#for j in range(0,n):
# s += "act" + str(j)
# if j < n-1:
# s += ","
#s += "} -> {request" + str(i) + "}};\n"
s += "\t{{request" + str(i) + "},{act" + str(i) + "} -> {request" + str(i) + "}};\n"
s += "\t{{request" + str(i) + ",act" + str(i) + "},{"
for j in range(0,n):
if i != j:
s += "act" + str(j) + ","
s += "lock} -> {in" + str(i) + ",lock}};\n"
s += "\t{{in" + str(i) + ",act" + str(i) + "},{} -> {out" + str(i) + ",done}};\n"
s += "\t{{in" + str(i) + "},{act" + str(i) + "} -> {in" + str(i) + "}};\n"
print s
print "\t{{lock},{done} -> {lock}};"
print "}"
s = "context-entities {"
for i in range(0,n):
s += "act" + str(i)
if i < n-1:
s += ","
s += "}\n"
print s
s = "initial-contexts { {"
for i in range(0,n):
s += "out" + str(i)
if i < n-1:
s += ","
s += "} }\n"
print s
#print "rsctl-property { A[{act1}]G(A[{act1}]F(in1)) }"
if f == 1:
print "rsctl-property { A[{act1}]F(in1) }"
elif f == 2:
print "rsctl-property { E[{act1}]F(in1) }"
elif f == 3:
s = "rsctl-property { AG("
for i in range(0,n):
for j in range(i+1,n):
s += "~(in" + str(i) + " AND in" + str(j) + ")"
if i < n-2:
s += " AND "
s += ") }"
print s
else:
exit(111)

View File

@@ -1,117 +0,0 @@
#!/usr/bin/env python
from sys import argv,exit
OPTIONS_STR = """
options { use-context-automaton; make-progressive; };
"""
PROC_STR = """
proc{:d} {{
{{{{out}}, {{}} -> {{approach}}}};
{{{{approach}}, {{req}} -> {{req}}}};
{{{{allowed}}, {{}} -> {{in}}}};
{{{{in}}, {{}} -> {{out,leave}}}};
{{{{req}}, {{in}} -> {{req}}}};
}};
"""
CA_STR = """
context-automaton {{
states {{ init, green, red }};
init-state {{ init }};
transitions {{
{:s}
}};
}};
"""
PROPERTY_STR = """
rsctlk-property {{ {:s} : {:s} }};
"""
#################################################################
if len(argv) < 1:
print("Usage: {:s} <number of processes>".format(argv[0]))
exit(100)
n = int(argv[1])
assert n > 1, "number of proc must be > 1"
out = ""
out += OPTIONS_STR
out += "reactions {\n"
for i in range(n):
out += PROC_STR.format(i)
out += "};\n"
transitions = ""
init_trans = 8*" " + "{ "
for i in range(n):
init_trans += "proc{:d}={{out}} ".format(i)
init_trans += "}: init -> green;\n"
transitions += init_trans
for i in range(n):
transitions += "{:s}{{ proc{:d}={{allowed}} }}: green -> red : proc{:d}.req;\n".format(8*" ", i, i)
no_req_cond = "~proc0.req"
for i in range(1, n):
no_req_cond += " AND ~proc{:d}.req".format(i)
for i in range(n):
transitions += "{:s}{{ proc{:d}={{}} }}: green -> green : {:s};\n".format(8*" ", i, no_req_cond)
for i in range(n):
transitions += "{:s}{{ proc{:d}={{}} }}: red -> green : proc{:d}.leave;\n".format(8*" ", i, i)
no_leave_cond = "~proc0.leave"
for i in range(1, n):
no_leave_cond += " AND ~proc{:d}.leave".format(i)
for i in range(n):
transitions += "{:s}{{ proc{:d}={{}} }}: red -> red : {:s};\n".format(8*" ", i, no_leave_cond)
out += CA_STR.format(transitions)
## f1
#formula = "EF( proc0.in )"
#out += PROPERTY_STR.format("f1",formula)
# f1
formula = "EF( E<proc0.allowed>X( proc0.in ) )"
for i in range(1, n):
formula += " AND EF( E<proc{:d}.allowed>X( proc{:d}.in ) )".format(i, i)
out += PROPERTY_STR.format("f1",formula)
# f2
formula = "EF( proc0.approach"
for i in range(1, n):
formula += " AND proc{:d}.approach".format(i)
formula += " )"
out += PROPERTY_STR.format("f2",formula)
# f3
subf = "~proc1.in"
for i in range(2, n):
subf += " AND ~proc{:d}.in".format(i)
formula = "AG( proc0.in IMPLIES K[proc0]({:s}) )".format(subf)
out += PROPERTY_STR.format("f3",formula)
# f4
subf = "~proc1.in"
for i in range(2, n):
subf += " AND ~proc{:d}.in".format(i)
all_agents = "proc0"
for i in range(1, n):
all_agents += ",proc{:d}".format(i)
formula = "AG( proc0.in IMPLIES C[{:s}]({:s}) )".format(all_agents,subf)
out += PROPERTY_STR.format("f4",formula)
print(out)