Explorar el Código

реализовал троичные функции

p.kushnir hace 10 años
padre
commit
223d80484b
Se han modificado 5 ficheros con 214 adiciones y 15 borrados
  1. 9 0
      ncl/base.go
  2. 3 1
      ncl/control.go
  3. 1 11
      ncl/std/basics.go
  4. 4 3
      ncl/std/pins.go
  5. 197 0
      tri/tri.go

+ 9 - 0
ncl/base.go

@@ -1,5 +1,14 @@
 package ncl
 
+/*
+ * NCL - Null Convention Logic, с троичной базой. Суть такова, помимо основых входов выходов имеется дополнительный сигнал валидности, его истинность означает, что на соотв. выходе результат верный. Для примера, есть сумматор, два входа, один выход, если на входе А валидный сигнал, а на Б невалидный сигнал, то на выходе сумматора будет невалидный сигнал. Эта невалидность будет подана на вход следующего элемента и т.д. То есть, элементы отработают только тогда, когда для них готовы данные на входе.
+
+Моделирование происходит на основе передачи значений от объектов-выходов через объекты-точки соединения к объектам-входам. В основе каждого объекта лежит горутина, а взаимодействие идет через каналы, то есть, у элементов нет общего тактового генератора. Таким образом каждый вход элемента представляет собой реализацию операции асинхронной логики - венъюнкция. Переключение сигнала данных происходит на фоне неизменности сигнала валидации.
+
+Все элементы расположены на макетной плате с набором точек. Макетная плата в свою очередь тоже является элементом, таким образом реализуется компонентность модели. К точкам припаиваются входы и выходы. Ток идет от выходов к входам, при этом короткое замыкание охраняется для каждой точки, то есть, невозможно подать в одну точку разные сигналы. В идеале, должен присутсвовать только один валидный сигнал из набора входов.
+
+В силу итеративной природы программ, невозможно непрерывное отслеживание значения переменной. Отсюда имеем вероятность пропуска валидного значения, однако, на плате в реальном проекте всегда присутствуют постоянно валидные источники сигнала - пины питания и триггеры-ячейки памяти, и вся схема зависит от их состояния, и не может произвольно это состояние сменить.
+*/
 import (
 	"sim3/tri"
 )

+ 3 - 1
ncl/control.go

@@ -4,11 +4,13 @@ import (
 	"time"
 )
 
+var slow time.Duration = time.Duration(time.Millisecond * 100)
+
 func Step(obj interface{}, step func()) {
 	do := func() {
 		for {
 			step()
-			time.Sleep(time.Duration(time.Millisecond * 200))
+			time.Sleep(slow)
 		}
 	}
 	do()

+ 1 - 11
ncl/std/basics.go

@@ -46,7 +46,7 @@ func NewNot() ncl.Element {
 		ncl.Step(n, func() {
 			ok, val := n.I.Select()
 			if ok {
-				n.O.Validate(true, notMap[val])
+				n.O.Validate(true, tri.Not(val))
 			} else {
 				n.O.Validate(false)
 			}
@@ -65,13 +65,3 @@ func NewBuffer() ncl.Element {
 	}(b)
 	return b
 }
-
-var notMap map[tri.Trit]tri.Trit
-
-func init() {
-	// таблицы истинности
-	notMap = make(map[tri.Trit]tri.Trit)
-	notMap[tri.TRUE] = tri.FALSE
-	notMap[tri.FALSE] = tri.TRUE
-	notMap[tri.NIL] = tri.NIL
-}

+ 4 - 3
ncl/std/pins.go

@@ -59,20 +59,21 @@ func (p *point) Solder(pins ...ncl.Pin) {
 }
 
 func (p *point) sel() (meta tri.Trit, signal tri.Trit) {
+	meta, signal = tri.FALSE, tri.NIL
 	for _, _x := range p.pins {
 		switch x := _x.(type) {
 		case *out:
+			assert.For(meta == tri.FALSE, 100)
 			meta := <-x.meta
 			if meta == tri.TRUE {
-				data := <-x.signal
-				return meta, data
+				signal = <-x.signal
 			}
 		case *in:
 		default:
 			halt.As(100)
 		}
 	}
-	return tri.FALSE, tri.NIL
+	return
 }
 
 func (p *point) set(meta tri.Trit, signal tri.Trit) {

+ 197 - 0
tri/tri.go

@@ -1,5 +1,6 @@
 package tri
 
+/* троичная логика */
 var TRUE Trit = Trit{n: false, t: true}
 var FALSE Trit = Trit{n: false, t: false}
 var NIL Trit = Trit{n: true, t: false}
@@ -18,3 +19,199 @@ func (t Trit) String() string {
 		return "%false"
 	}
 }
+
+func False(t Trit) bool {
+	return t == FALSE
+}
+
+func True(t Trit) bool {
+	return t == TRUE
+}
+
+func Nil(t Trit) bool {
+	return t == NIL
+}
+
+func Not(t Trit) Trit {
+	if t == TRUE {
+		return FALSE
+	} else if t == FALSE {
+		return TRUE
+	} else {
+		return NIL
+	}
+}
+
+func Impl(p, q Trit) Trit {
+	if False(p) && False(q) {
+		return TRUE
+	} else if False(p) && True(q) {
+		return TRUE
+	} else if True(p) && False(q) {
+		return FALSE
+	} else if True(p) && True(q) {
+		return TRUE
+	} else if True(p) && Nil(q) {
+		return NIL
+	} else if Nil(p) && False(q) {
+		return NIL
+	} else if False(p) && Nil(q) {
+		return TRUE
+	} else if Nil(p) && Nil(q) {
+		return TRUE
+	} else if Nil(p) && True(q) {
+		return TRUE
+	}
+	panic(0)
+}
+
+func CNot(t Trit) Trit {
+	if t == TRUE {
+		return FALSE
+	} else if t == FALSE {
+		return NIL
+	} else {
+		return TRUE
+	}
+}
+
+func Or(p, q Trit) Trit {
+	return Impl(Impl(p, q), q)
+}
+
+func And(p, q Trit) Trit {
+	return Not(Or(Not(p), Not(q)))
+}
+
+func Eq(p, q Trit) Trit {
+	return And(Impl(p, q), Impl(q, p))
+}
+
+func This(x int) Trit {
+	if x == 1 {
+		return TRUE
+	} else if x == 0 {
+		return NIL
+	} else if x == -1 {
+		return FALSE
+	}
+	panic(0)
+}
+
+func Ord(t Trit) int {
+	if t == FALSE {
+		return -1
+	} else if t == NIL {
+		return 0
+	} else if t == TRUE {
+		return 1
+	}
+	panic(0)
+}
+
+func Sum3(p, q Trit) Trit {
+	switch Ord(p) {
+	case -1:
+		return q
+	case 0:
+		if False(q) {
+			return NIL
+		} else if Nil(q) {
+			return TRUE
+		} else {
+			return FALSE
+		}
+	case 1:
+		if False(q) {
+			return TRUE
+		} else if Nil(q) {
+			return FALSE
+		} else {
+			return NIL
+		}
+	default:
+		panic(0)
+	}
+}
+
+func Sum3r(p, q Trit) Trit {
+	return CNot(CNot(Sum3(p, q)))
+}
+
+func CarryS(p, q Trit) Trit {
+	switch Ord(p) {
+	case -1:
+		return FALSE
+	case 0:
+		if True(q) {
+			return NIL
+		} else {
+			return FALSE
+		}
+	case 1:
+		if False(q) {
+			return FALSE
+		} else {
+			return NIL
+		}
+	default:
+		panic(0)
+	}
+}
+
+func CarrySr(p, q Trit) Trit {
+	if False(p) && False(q) {
+		return FALSE
+	} else if True(p) && True(q) {
+		return TRUE
+	} else {
+		return NIL
+	}
+}
+
+func Mul3(p, q Trit) Trit {
+	switch Ord(p) {
+	case -1:
+		return FALSE
+	case 0:
+		return q
+	case 1:
+		if False(q) {
+			return FALSE
+		} else if Nil(q) {
+			return TRUE
+		} else {
+			return NIL
+		}
+	default:
+		panic(0)
+	}
+}
+
+func CarryM(p, q Trit) Trit {
+	if True(p) && True(q) {
+		return NIL
+	} else {
+		return FALSE
+	}
+}
+
+func Mul3r(p, q Trit) Trit {
+	if Nil(p) && Nil(q) {
+		return NIL
+	} else {
+		if p == q {
+			return TRUE
+		} else {
+			return FALSE
+		}
+	}
+}
+
+func Webb(p, q Trit) Trit {
+	return CNot(Or(p, q))
+}
+
+func Mod(t Trit) Trit {
+	return Or(t, Not(t))
+}