Skip to content

Instantly share code, notes, and snippets.

@mgronhol
Created July 6, 2014 19:07
Show Gist options
  • Save mgronhol/a90b31291e14382a7e56 to your computer and use it in GitHub Desktop.
Save mgronhol/a90b31291e14382a7e56 to your computer and use it in GitHub Desktop.
Provable PLC first test (xor)
#!/usr/bin/env python
def generate_test_cases(N):
M = 2**N
out = []
for i in range( M ):
case = [ (i >> j & 0x01) == 1 for j in range( N ) ]
out.append( tuple( case ) )
return out
class Context( object ):
def __init__( self ):
self.inputs = {}
def __call__( self, node ):
if isinstance( node, Input ):
self.inputs[ (node.name, "input") ] = node
def get(self):
return [v for (k,v) in self.inputs.items() ]
class Input( object ):
def __init__(self, name):
self.state = False
self.name = name
def get(self):
return self.state
def set( self, value ):
self.state = value
def __call__(self, ctx ):
ctx( self )
return self.get()
class And( object ):
def __init__( self, lhs, rhs ):
self.lhs = lhs
self.rhs = rhs
def __call__(self, ctx):
v0 = self.lhs( ctx )
v1 = self.rhs( ctx )
return v0 and v1
class Or( object ):
def __init__( self, lhs, rhs ):
self.lhs = lhs
self.rhs = rhs
def __call__(self, ctx ):
v0 = self.lhs( ctx )
v1 = self.rhs( ctx )
return v0 or v1
class Not( object ):
def __init__( self, lhs ):
self.lhs = lhs
def __call__( self, ctx ):
return not self.lhs( ctx )
class Intermediate( object ):
def __init__( self, lhs, name = None ):
self.lhs = lhs
self.name = name
def __call__( self, ctx ):
if self.name:
ctx( self )
return self.lhs( ctx )
class Event( object ):
def __init__( self, name ):
self.name = name
self.inputs = []
self.outputs = []
def addInput( self, lhs, rhs ):
self.inputs.append( (lhs, rhs) )
def addOutput( self, lhs, rhs ):
self.outputs.append( (lhs, rhs) )
def __call__( self, ctx ):
vals = [lhs(ctx) == rhs for (lhs, rhs) in self.inputs]
if all( vals ):
for (lhs, rhs) in self.outputs:
lhs.set( rhs )
return True
return False
def resolve(self):
null = lambda x: None
for (lhs, rhs) in self.inputs:
ctx = Context()
lhs(ctx)
original = ctx.get()
cases = generate_test_cases( len(original) )
results = {}
for case in cases:
for (value, inp) in zip( case, original ):
inp.set(value)
results[case] = lhs(null) == rhs
print (lhs,rhs), results
########################################################################
input0 = Input( 0 )
input1 = Input( 1 )
null = lambda x: None
xor = And( Or( input0, input1 ), Not( And( input0, input1 ) ) )
input0.set( False )
input1.set( False )
print input0.get(), "xor", input1.get(), "=", xor(null)
input0.set( True )
input1.set( False )
print input0.get(), "xor", input1.get(), "=", xor(null)
input0.set( True )
input1.set( True )
print input0.get(), "xor", input1.get(), "=", xor(null)
input0.set( False )
input1.set( True )
print input0.get(), "xor", input1.get(), "=", xor(null)
ctx = Context()
xor(ctx)
print ctx.get()
print ""
print ""
print "Resolve test"
print ""
inp2 = Intermediate( xor, "X" )
event = Event("xor test")
event.addInput( inp2, True )
event.resolve()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment