Created
July 6, 2014 19:07
-
-
Save mgronhol/a90b31291e14382a7e56 to your computer and use it in GitHub Desktop.
Provable PLC first test (xor)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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