Created
October 19, 2010 14:18
-
-
Save cthom06/634262 to your computer and use it in GitHub Desktop.
Boolean Circuits (ish) using go channels
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
// A fun little experiment making boolean circuits with channels | |
// It's pretty slow (especially with GOMAXPROCS > 1), but neat | |
// Originally, I had made all the gates structs with methods, etc, | |
// but they can all be done as functions thanks to closures/gc. | |
package circ | |
func NAND(in1, in2 <-chan bool) <-chan bool { | |
out := make(chan bool) | |
go func() { | |
for { | |
b1 := <-in1 | |
b2 := <-in2 | |
out <- !(b1 && b2) | |
} | |
}() | |
return out | |
} | |
//Helper for splicing | |
func Split(in <-chan bool) (<-chan bool, <-chan bool) { | |
out := []chan bool{make(chan bool), make(chan bool)} | |
go func() { | |
for { | |
b := <-in | |
out[0] <- b | |
out[1] <- b | |
} | |
}() | |
return out[0], out[1] | |
} | |
func NOT(in <-chan bool) <-chan bool { | |
return NAND(Split(in)) | |
} | |
func AND(in1, in2 <-chan bool) <-chan bool { | |
return NOT(NAND(in1, in2)) | |
} | |
func OR(in1, in2 <-chan bool) <-chan bool { | |
return NAND(NOT(in1), NOT(in2)) //This is starting to feel like FP | |
} | |
func NOR(in1, in2 <-chan bool) <-chan bool { | |
return NOT(OR(in1, in2)) | |
} | |
func XOR(in1, in2 <-chan bool) <-chan bool { | |
tin1, tin2 := Split(in1) | |
tin3, tin4 := Split(in2) | |
tin5, tin6 := Split(NAND(tin2, tin4)) | |
return NAND(NAND(tin1, tin5), NAND(tin3, tin6)) | |
} | |
func XNOR(in1, in2 <-chan bool) <-chan bool { | |
return NOT(XOR(in1, in2)) | |
} | |
//The functions below here are really just examples | |
func HalfAdder(in1, in2 <-chan bool) (<-chan bool, <-chan bool) { | |
tin1, tin3 := Split(in1) | |
tin2, tin4 := Split(in2) | |
return XOR(tin1, tin2), AND(tin3, tin4) | |
} | |
func Adder(in1, in2, cin <-chan bool) (<-chan bool, <-chan bool) { | |
s, c1 := HalfAdder(in1, in2) | |
sout, c2 := HalfAdder(s, cin) | |
cout := OR(c1, c2) | |
return sout, cout | |
} | |
func MultiBitAdder(in1 []chan bool, in2 []chan bool) ([]<-chan bool, <-chan bool) { | |
if len(in1) != len(in2) { | |
return nil, nil | |
} | |
out := make([]<-chan bool, len(in1)) | |
var carry <-chan bool | |
for i := 0; i < len(out); i++ { | |
if i == 0 { | |
out[i], carry = HalfAdder(in1[i], in2[i]) | |
} else { | |
out[i], carry = Adder(in1[i], in2[i], carry) | |
} | |
} | |
return out, carry | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment