Skip to content

Instantly share code, notes, and snippets.

@cthom06
Created October 19, 2010 14:18
Show Gist options
  • Save cthom06/634262 to your computer and use it in GitHub Desktop.
Save cthom06/634262 to your computer and use it in GitHub Desktop.
Boolean Circuits (ish) using go channels
// 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