Commit 4b03324f authored by Lars Schieffer's avatar Lars Schieffer
Browse files

add strategies and update tests

parent 4938fb88
......@@ -28,9 +28,10 @@ else:
syntax = not commandline.getDisableCheck()
r2i = commandline.getR2IFlag()
experiment = commandline.getExperimentValues()
strategy = commandline.getStrategy()
try:
jani = filesystem.loadJANI(path, syntax)
pinsPlugin = PINS(jani, experiment, r2i)
pinsPlugin = PINS(jani, experiment, r2i, strategy)
except ValidationError as error:
print(error)
sys.exit(1)
......
......@@ -7,7 +7,7 @@ from src.pins.modules.locations import Locations
from src.pins.modules.stateVector import StateVector
def instancesOf(model: dict, functions: dict) -> list:
def instancesOf(model: dict, functions: dict, mode: str) -> list:
"""
Function Description:
Customise jani-model automata, so that valid PINS model composition.
......@@ -17,6 +17,8 @@ def instancesOf(model: dict, functions: dict) -> list:
Object of jani-model
functions: dict
Defined functions in PINS model
mode: str
Mode of grouping strategy
"""
system = model["system"]
elements = [element["automaton"] for element in system["elements"]]
......@@ -55,19 +57,52 @@ def instancesOf(model: dict, functions: dict) -> list:
for index, label in enumerate(syncVector):
if label:
edges.append(instances[index][label])
if isLocal(syncVector) or ndProblem(syncVector, ndLabels):
edges = flattenOf(edges)
for edge in edges:
updatedLabel = str(len(updatedSyncs))
synchronise = []
grouping = [
isLocal(syncVector),
ndProblem(syncVector, ndLabels),
mode == "FLATTEN",
]
if any(grouping):
if mode == "SYMBOLIC":
original, symbolic = symbolicOf(edges)
labels = []
for index, entry in enumerate(syncVector):
originalLabel = str(len(updatedSyncs))
automatonLabels = []
if entry:
updatedInstances[index][updatedLabel] = [edge.pop(0)]
synchronise.append(updatedLabel)
else:
synchronise.append(None)
synchronisation = {"result": result, "synchronise": synchronise}
updatedSyncs.append(synchronisation)
edges = [arc[0] for arc in original.pop(0)]
if edges:
automatonLabels.append(originalLabel)
updatedInstances[index][originalLabel] = edges
for unique, edge in enumerate(symbolic.pop(0)):
symbolicLabel = originalLabel + "_" + str(unique)
automatonLabels.append(symbolicLabel)
updatedInstances[index][symbolicLabel] = edge
labels.append(automatonLabels)
labels = flattenOf(labels)
for label in labels:
synchronise = []
for index, entry in enumerate(syncVector):
if entry:
synchronise.append(label.pop(0))
else:
synchronise.append(None)
synchronisation = {"result": result, "synchronise": synchronise}
updatedSyncs.append(synchronisation)
else:
edges = flattenOf(edges)
for edge in edges:
updatedLabel = str(len(updatedSyncs))
synchronise = []
for index, entry in enumerate(syncVector):
if entry:
updatedInstances[index][updatedLabel] = [edge.pop(0)]
synchronise.append(updatedLabel)
else:
synchronise.append(None)
synchronisation = {"result": result, "synchronise": synchronise}
updatedSyncs.append(synchronisation)
else:
updatedLabel = str(len(updatedSyncs))
synchronise = []
......@@ -167,6 +202,38 @@ def flattenOf(edges: list) -> list:
return flattened
def symbolicOf(edges: list) -> list:
"""
Function Description:
Create symbolic grouping strategy
Function Parameters:
edges:list
Each entry contains the list of participating edges in automaton instance.
"""
original = list()
symbolic = list()
for automaton in edges:
locations = dict()
for edge in automaton:
name = edge["location"]
if name not in locations:
locations[name] = []
locations[name] += [edge]
automatonOriginal = list()
automatonSymbolic = list()
for location, edges in locations.items():
if len(edges) > 1:
for edge in edges:
automatonSymbolic.append([edge])
else:
automatonOriginal.append(edges)
original.append(automatonOriginal)
symbolic.append(automatonSymbolic)
return original, symbolic
def updateGuardOf(edge: dict, localNames: set, automaton: str, functions: dict) -> dict:
"""
Function Description:
......
from enum import Enum, auto
def changesOf(automaton: str, destination: dict) -> list:
"""
Function Description:
......
......@@ -43,10 +43,12 @@ class Model:
Flag if real values should be cast to integer
experiment: dict
Run experiment on JANI-Model
mode: str
Mode of grouping strategy
"""
def __init__(
self, janiModel: dict, real2int: bool, experiment={},
self, janiModel: dict, real2int: bool, mode: str, experiment={},
):
isSupported(janiModel, real2int)
automata = janiModel["automata"]
......@@ -54,7 +56,7 @@ class Model:
self.__stateVector = self.__createStateVector(janiModel, real2int)
self.__janiFunctions = functionsOf(janiModel, self.__stateVector)
self.__locations = self.__createLocations(automata, self.__janiFunctions)
groups, guards, actions = self.__createTransitionGroups(janiModel)
groups, guards, actions = self.__createTransitionGroups(janiModel, mode)
self.__transitionGroups = groups
self.__guards = guards
self.__actions = actions
......@@ -112,7 +114,7 @@ class Model:
return stateVector
def __createTransitionGroups(
self, janiModel: dict
self, janiModel: dict, mode: str
) -> (List[TransitionGroup], ModelGuards, Actions):
"""
Function Description:
......@@ -121,8 +123,10 @@ class Model:
Function Parameters:
janiModel: dict
Reference to JANI-Model
mode: str
Mode of grouping strategy
"""
instances, syncs = strategy.instancesOf(janiModel, self.__janiFunctions)
instances, syncs = strategy.instancesOf(janiModel, self.__janiFunctions, mode)
system = janiModel["system"]
elements = [element["automaton"] for element in system["elements"]]
names = []
......@@ -161,7 +165,7 @@ class Model:
update = transientUpdates[location]
locations[updated][location] = update
synchronisedGroup = TransitionGroup(
result, group, groupGuards, self.__stateVector, locations
result, group, groupGuards, self.__stateVector, locations, mode
)
transitionGroups.append(synchronisedGroup)
......@@ -187,7 +191,12 @@ class Model:
groupGuards, self.__stateVector, self.__locations
)
tauGroup = TransitionGroup(
"tau", [edge], [groupGuards], self.__stateVector, locations
"tau",
[edge],
[groupGuards],
self.__stateVector,
locations,
mode,
)
transitionGroups.append(tauGroup)
return transitionGroups, modelGuards, edgeLabels
......@@ -63,6 +63,8 @@ class TransitionGroup:
The dependent state vector, for creating read and write dependencies
locations: dict
Edges location in automata
mode: str
Mode of grouping strategy
"""
def __init__(
......@@ -72,6 +74,7 @@ class TransitionGroup:
guards: list,
stateVector: StateVector,
locations: dict,
mode: str,
):
self.__indent = 4 * " "
self.__label = label
......@@ -79,11 +82,11 @@ class TransitionGroup:
self.__guards = guards
self.__locations = locations
self.__write = self.__writeBy(self.__edges, stateVector)
self.__read = (
self.__readBy(self.__edges, stateVector)
.union(self.__transientDependencies(self.__locations, stateVector))
.union(self.__write)
self.__read = self.__readBy(self.__edges, stateVector).union(
self.__transientDependencies(self.__locations, stateVector)
)
if mode == "MIXED" or mode == "SYMBOLIC":
self.__read = self.__read.union(self.__write)
def createGuardsString(self, guardPositions: dict) -> str:
"""
......@@ -449,10 +452,16 @@ class TransitionGroup:
slot, modelLocations, stateVector, str(readIndex - 1)
)
else:
value = string.perform(slot, modelLocations, stateVector)
slotVariableCode = variableDeclareString.format(
identifier, str(readIndex), value
)
if slot in stateVector.getPositions():
value = string.perform(slot, modelLocations, stateVector)
else:
value = ""
if value:
slotVariableCode = variableDeclareString.format(
identifier, str(readIndex), value
)
else:
slotVariableCode = "int {}{};".format(identifier, str(readIndex))
declaredVariables.append(self.__indent + slotVariableCode)
return declaredVariables
......
import importlib.resources as resources
import src.grouping.strategy as strategy
from src import placeholder
from src.pins.codeCreation.guardImplementation import guardImplementationOf
from src.pins.codeCreation.matrices import matricesOf
......@@ -44,14 +43,19 @@ class PINS:
If JANI model allows experiments, values can be found here
real2int: bool
Flag for running real to integer cast during creation of model
mode: str
Mode of grouping strategy
"""
def __init__(
self, janiModel: dict, experiment: dict, real2int: bool,
self, janiModel: dict, experiment: dict, real2int: bool, strategy: str
):
# Create datastructure for holding information about PINS model
self.pinsModel = Model(
janiModel=janiModel, experiment=experiment, real2int=real2int,
janiModel=janiModel,
experiment=experiment,
real2int=real2int,
mode=strategy,
)
# Create source code of LTSmin frontend
......
......@@ -66,10 +66,27 @@ def trace() -> dict:
return traceOption
def mode() -> dict:
"""
Function Description:
Grouping Strategy Mode
"""
mode = {
"id": "mode",
"name": "Grouping Strategy",
"description": "Set Grouping Strategy",
"category": "JANI2PINS",
"is-global": False,
"type": ["FLATTEN", "MIXED", "SYMBOLIC"],
"default-value": "FLATTEN",
}
return mode
def create() -> list:
"""
Function Description:
Create all parameters for ltsmin analysis engine
"""
parameters = [real2int(), backend(), command(), trace()]
parameters = [real2int(), mode(), backend(), command(), trace()]
return parameters
......@@ -32,10 +32,27 @@ def experiment() -> dict:
return experimentValues
def mode() -> dict:
"""
Function Description:
Grouping Strategy Mode
"""
mode = {
"id": "mode",
"name": "Grouping Strategy",
"description": "Set Grouping Strategy",
"category": "JANI2PINS",
"is-global": False,
"type": ["FLATTEN", "MIXED", "SYMBOLIC"],
"default-value": "FLATTEN",
}
return mode
def create() -> list:
"""
Function Description:
Create all parameters for ltsmin model transformers
"""
parameters = [real2int(), experiment()]
parameters = [real2int(), experiment(), mode()]
return parameters
......@@ -51,6 +51,7 @@ class Model:
self.__trace = False
self.__experimentValues = ""
self.__real2int = False
self.__mode = "FLATTEN"
self.__handleParameters(parameters)
self.__saveModel(model)
......@@ -63,7 +64,9 @@ class Model:
experiment: str
Values of not initialized constants in JANI model
"""
errors = jani2pins.execute(self.__location, experiment, self.__real2int)
errors = jani2pins.execute(
self.__location, experiment, self.__real2int, self.__mode
)
return errors
def executeLTSmin(self) -> str:
......@@ -126,6 +129,8 @@ class Model:
self.__experimentValues = parameter["value"]
elif parameter["id"] == "real2int":
self.__real2int = parameter["value"]
elif parameter["id"] == "mode":
self.__mode = parameter["value"]
else:
print(repr(parameter))
......
......@@ -6,7 +6,7 @@ import src.utilities.parser.expression.toExpression as expression
from src.pins.plugin import PINS
def execute(location: str, experiment: str, real2int: bool) -> str:
def execute(location: str, experiment: str, real2int: bool, mode: str) -> str:
"""
Function Description:
Create PINS model in filesystem by executing jani2pins parser and return occurring
......@@ -18,12 +18,17 @@ def execute(location: str, experiment: str, real2int: bool) -> str:
experiment: str
Values of not initialized constants in JANI model
real2int: bool
Should real values cast to integer?
Should real values get cast to integer?
mode: str
Grouping strategy mode
"""
print(mode)
try:
model = filesystem.loadJANI(path.join(location, "model.jani"), False)
pinsPlugin = PINS(model, real2int, expression.createExperiments(experiment))
pinsPlugin = PINS(
model, real2int, expression.createExperiments(experiment), mode
)
except Exception as error:
return str(error)
# Write Plugin to File
......
......@@ -17,7 +17,13 @@ commandLine.add_argument(
"--output",
metavar="PATH",
default="./",
help='Directory of PINS model (default: "%(default)s"),',
help='Directory of PINS model (default: "%(default)s")',
)
commandLine.add_argument(
"--strategy",
choices=["FLATTEN", "MIXED", "SYMBOLIC"],
default="SYMBOLIC",
help='Grouping strategy of automata edges (default: "%(default)s")',
)
commandLine.add_argument(
"--ltsmin",
......@@ -90,3 +96,7 @@ def getPluginName():
def getDisableCheck():
return arguments.disableCheck
def getStrategy():
return arguments.strategy
#include <jani2pinsPlugin.h>
#ifndef GROUPAMOUNT
#define GROUPAMOUNT 30
#endif
//Create TransitionGroupGuards
guard_t **createTransitionGroupGuardInformation()
{
// Guards of each transition group
int *transitionGuards[GROUPAMOUNT] = {(int[]){0,1},(int[]){2,3},(int[]){3,4},(int[]){2,5},(int[]){4,5},(int[]){2,6},(int[]){4,6},(int[]){2,7},(int[]){4,7},(int[]){8,9},(int[]){10,8},(int[]){11,12},(int[]){12,13},(int[]){11,12},(int[]){12,13},(int[]){14,8},(int[]){15,16},(int[]){16,17},(int[]){15,16},(int[]){16,17},(int[]){18,3},(int[]){18,19},(int[]){20},(int[]){21},(int[]){22},(int[]){23},(int[]){24},(int[]){25},(int[]){26},(int[]){27}};
int transitionGuardsSizes[GROUPAMOUNT] = {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1};
guard_t **guard_info = malloc(GROUPAMOUNT * sizeof(guard_t *));
for (int i = 0; i < GROUPAMOUNT; i++)
{
guard_info[i] = malloc(sizeof(int[transitionGuardsSizes[i] + 1]));
memcpy(guard_info[i]->guard, transitionGuards[i], transitionGuardsSizes[i] * sizeof(int));
guard_info[i]->count = transitionGuardsSizes[i];
}
return guard_info;
}
#include <jani2pinsPlugin.h>
// Read dependencies to state vector
int readMatrix[30][23] = {{1,0,1,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1},{1,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1},{1,1,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1},{1,1,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1},{1,1,0,0,0,1,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,1},{1,1,0,0,0,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1},{1,1,0,0,0,1,0,0,0,0,1,0,1,1,1,0,0,0,0,0,0,0,1},{1,1,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1},{1,1,0,0,0,1,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,1},{1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1},{0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,1},{0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,1},{0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,1},{0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,1},{1,0,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,1,0,1,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1},{1,0,0,1,0,1,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1},{1,0,0,1,0,1,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1},{1,0,0,1,0,1,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1},{0,1,0,1,0,0,0,0,0,1,0,1,1,1,0,1,1,1,0,1,1,1,1},{0,1,0,1,0,0,0,0,0,1,0,1,1,1,0,1,1,1,0,1,1,1,1},{1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},{0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,1},{0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,1},{0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,1},{0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,1}};
int *readDependencies(int group){
return readMatrix[group];
}
// Write Dependencies
int writeMatrix[30][23] = {{1,0,1,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0},{1,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0},{1,1,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0},{1,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0},{1,1,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0},{1,1,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0},{1,1,0,0,0,1,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0},{1,1,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0},{1,1,0,0,0,1,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0},{1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},{0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,1},{0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1},{0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,1},{0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1},{1,0,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,1,0,1,0,1,0,1,0,1,1,0,0,0,0,0,0,0,0,1,0},{1,0,0,1,0,1,0,1,0,1,0,1,1,0,0,0,0,0,0,0,0,1,0},{1,0,0,1,0,1,0,1,0,1,0,1,1,0,0,0,0,0,0,0,0,1,0},{1,0,0,1,0,1,0,1,0,1,0,1,1,0,0,0,0,0,0,0,0,1,0},{0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0},{0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0},{1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0},{0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0},{0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0},{0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0}};
int *writeDependencies(int group){
return writeMatrix[group];
}
// Label Dependencies
int labelMatrix[28][23] = {{1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0},{1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0},{1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0},{1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},{0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},{0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0},{0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},{0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,0,0,0},{0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},{1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},{0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0},{1,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0},{0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,0,0,0,0},{0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,0,0,0,0},{0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,0,0,0,0}};
int *labelDependencies(int label){
return labelMatrix[label];
}
// Do-not-accord
int DNAMatrix[30][30] = {{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,0,0,0},{0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,0,0,0,1,1,0,0,0,0,1,1,1,1},{0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,0,0,0,1,1,0,0,0,0,1,1,1,1},{0,1,1,1,1,1,<