Skip to content

Instantly share code, notes, and snippets.

@GlulkAlex
Created March 4, 2017 12:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GlulkAlex/3e0c6adf3531121d39317a65d83d1e9b to your computer and use it in GitHub Desktop.
Save GlulkAlex/3e0c6adf3531121d39317a65d83d1e9b to your computer and use it in GitHub Desktop.
Exercise from Discrete Event Simulation Lecture of Functional Program Design In Scala course
#!/usr/bin/env scala
// for The `bash` `shell script` './script.sh'
// but App main object warper must be disabled|excluded
import scala.io.AnsiColor._
// it is imported twice in the same scope by
//import scala.Console._
//
//
/*object digital_Circuit_Logic_Gates extends App */{
/* A digital circuit is composed
of wires
and of functional components.
*/
// conducting only {true|false} signals
class Wire {
// error: abstract member may not have private modifier
private var signal: Boolean = true
//
def get_Signal: Boolean = signal
//
def set_Signal(s_Val: Boolean): Unit = {
//this.
signal = s_Val}
}
//
/*
The components have
a reaction time (or delay),
i.e. their outputs don't change immediately
after a change to their inputs.
*/
/** output is the inverse of its input */
def inverter(input: Wire, output: Wire): Unit = {
//output = !input
output.set_Signal(!input.get_Signal)
}
//
/** output is the conjunction of its inputs */
def and_Gate(
a1: Wire,
a2: Wire,
output: Wire
): Unit = {
//output = a1 && a2
output.set_Signal(a1.get_Signal && a2.get_Signal)
}
//
/** output is the disjunction of its inputs */
def or_Gate(
o1: Wire,
o2: Wire,
output: Wire
): Unit = {
//output = o1 || o2
output.set_Signal(o1.get_Signal || o2.get_Signal)
}
//
def half_Adder(
a: Wire, b: Wire, s: Wire, c: Wire
): Unit = {
val d = new Wire
val e = new Wire
//
or_Gate(a, b, d)
and_Gate(a, b, c)
inverter(c, e)
and_Gate(d, e, s)
}
//
def full_Adder(
a: Wire, b: Wire, cin: Wire, sum: Wire, cout: Wire
): Unit = {
val s = new Wire
val c1 = new Wire
val c2 = new Wire
//
half_Adder(b, cin, s, c1)
half_Adder(a, s, sum, c2)
or_Gate(c1, c2, cout)
}
//
def unknown_Gate(
a: Wire,
b: Wire,
c: Wire
): Unit = {
val d, e, f, g = new Wire
//
inverter(a, d)
inverter(b, e)
and_Gate(a, e, f)
and_Gate(b, d, g)
or_Gate(f, g, c)
}
//
def mark_String(
str: String,
expected_Val: Any,
actual_Val: Any
): String = if (
expected_Val == actual_Val
){
REVERSED + str + RESET
} else {
str
}
//
def log_2(x: Int): Int = (math.log(x) / math.log(2)).toInt
// scala> 3.toBinaryString
// res1: String = 11
//java.lang.Integer.parseInt(String s, int radix)
val combination_Size = 2
// pairs|combinations_Size|length
val range_Upper_Limit: Int = math.pow(2, combination_Size).toInt
val str_Max_Binary_Size = log_2(range_Upper_Limit)// + 1
val choices: Map[Char, Boolean] = Map('0' -> false, '1' -> true)
var results_Comparisons: Map[String, List[Boolean]] = Map(
"a_And_Not_B" -> List(),
"a_Equal_B" -> List(),
"a_And_Not_A_And_B" -> List(),
"a_Not_Equal_B" -> List(),
"Not_A_And_B" -> List()
)
val test_Wire = new Wire
//
println("(test_Wire = new Wire).get_Signal:" + test_Wire.get_Signal)
test_Wire.set_Signal(false)
println("(test_Wire.set_Signal(false).get_Signal:" + test_Wire.get_Signal)
println("Combinations of {0|1} of length:" + combination_Size)
println("000111".combinations(3).toList.mkString("\n"))
println(List(0, 1, 0).permutations.toArray.mkString("\n"))
(0 until range_Upper_Limit by 1).foreach(i => {
//
val b_Str = i.toBinaryString
val size_Diff = str_Max_Binary_Size - b_Str.size
val a = new Wire
val b = new Wire
val c = new Wire
//
if (size_Diff > 0) {
//
a.set_Signal(false)
b.set_Signal(choices(b_Str(0)))
//
println("0" * size_Diff + b_Str)
} else {
a.set_Signal(choices(b_Str(0)))
b.set_Signal(choices(b_Str(1)))
//
println(b_Str)
}
//
println("unknown_Gate(a:" + a.get_Signal +
", b:" + b.get_Signal +
", c:" + c.get_Signal + ")")
unknown_Gate(
a,
b,
c
)
val actual_Result = c.get_Signal
val a_And_Not_B = a.get_Signal && !b.get_Signal
val a_Equal_B = a.get_Signal == b.get_Signal
val a_And_Not_A_And_B = a.get_Signal && !(a.get_Signal && b.get_Signal)
val a_Not_Equal_B = a.get_Signal != b.get_Signal
val Not_A_And_B = !a.get_Signal && b.get_Signal
//
results_Comparisons += "a_And_Not_B" -> (
(actual_Result == a_And_Not_B) :: results_Comparisons.getOrElse("a_And_Not_B", List[Boolean]())
)
results_Comparisons += "a_Equal_B" -> (
(actual_Result == a_Equal_B) :: results_Comparisons.getOrElse("a_Equal_B", Nil)
)
results_Comparisons += "a_And_Not_A_And_B" -> (
(actual_Result == a_And_Not_A_And_B) :: results_Comparisons.getOrElse(
"a_And_Not_A_And_B", Nil)
)
results_Comparisons += "a_Not_Equal_B" -> (
(actual_Result == a_Not_Equal_B) :: results_Comparisons.getOrElse("a_Not_Equal_B", Nil)
)
results_Comparisons += "Not_A_And_B" -> (
(actual_Result == Not_A_And_B) :: results_Comparisons.getOrElse("Not_A_And_B", Nil)
)
//
println(
"c:" + c.get_Signal +
mark_String(
"\n?= (a && !b):" + a_And_Not_B, a_And_Not_B, actual_Result) +
//"\n?= (a && !b):" + a_And_Not_B +
mark_String(
"\n?= (a == b):" + a_Equal_B, a_Equal_B, actual_Result) +
//"\n?= (a == b):" + (a.get_Signal == b.get_Signal) +
mark_String(
"\n?= (a && !(a && b)):" + a_And_Not_A_And_B,
a_And_Not_A_And_B, actual_Result) +
//"\n?= (a && !(a && b)):" + (a.get_Signal && !(a.get_Signal && b.get_Signal)) +
mark_String(
"\n?= (a != b):" + a_Not_Equal_B, a_Not_Equal_B, actual_Result) +
//"\n?= (a != b):" + (a.get_Signal != b.get_Signal) +
mark_String(
"\n?= (!a && b):" + Not_A_And_B, Not_A_And_B, actual_Result) +
//"\n?= (!a && b):" + (!a.get_Signal && b.get_Signal) +
//" ?= (a * b):" + a.get_Signal == b.get_Signal +
"\n"
)
}
)
//
Console.println("digital_Circuit_Logic_Gates: ...")
println(
results_Comparisons
.filter{case (k, v) => v.forall(i => i)}
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment