Merge branch 'master' of https://github.com/PeterAaser/TDT4255_EX2
This commit is contained in:
commit
4a4717b312
5 changed files with 13 additions and 347 deletions
|
@ -3,6 +3,9 @@ Best viewed in emacs org mode.
|
|||
This is the coursework for the graded part of the TDT4255 course at NTNU.
|
||||
|
||||
* Instructions
|
||||
|
||||
#+ATTR_HTML: title="Join the chat at https://gitter.im/RISCV-FiveStage/community"
|
||||
[[https://gitter.im/RISCV-FiveStage/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge][file:https://badges.gitter.im/RISCV-FiveStage/community.svg]]
|
||||
To get started with designing your 5-stage RISC-V pipeline you should follow the
|
||||
[[./exercise.org][Exercise instructions]]
|
||||
|
||||
|
|
|
@ -46,8 +46,6 @@ val defaultVersions = Map(
|
|||
libraryDependencies ++= (Seq("chisel3","chisel-iotesters").map {
|
||||
dep: String => "edu.berkeley.cs" %% dep % sys.props.getOrElse(dep + "Version", defaultVersions(dep)) })
|
||||
|
||||
val versionOfScala = "2.12.4"
|
||||
|
||||
val fs2Version = "0.10.3"
|
||||
val catsVersion = "1.1.0"
|
||||
val catsEffectVersion = "0.10"
|
||||
|
|
|
@ -49,11 +49,18 @@ class InstructionFetch extends MultiIOModule {
|
|||
|
||||
|
||||
/**
|
||||
* Setup. You should not change this code
|
||||
* Setup.
|
||||
*
|
||||
* When you have added an instruction signal to this module you
|
||||
* should ensure that it is set to NOP during program loading.
|
||||
*
|
||||
* If not you will end up issuing instructions during program load
|
||||
* which will start executing before memory, registers and programs
|
||||
* are fully loaded.
|
||||
*/
|
||||
when(testHarness.IMEMsetup.setup) {
|
||||
PC := 0.U
|
||||
// TODO: You must set the instruction to Instruction.NOP here.
|
||||
// throw new Exception("Just making sure you're seeing the line above")
|
||||
// TODO: You should probably set the instruction to Instruction.NOP here.
|
||||
throw new Exception("Just making sure you're seeing the line above.\nYou can delete this exception now, it's found at line 64 at IF.scala")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,178 +0,0 @@
|
|||
package FiveStage
|
||||
import cats.data.Writer
|
||||
import cats._
|
||||
import cats.data.{ Op => _ }
|
||||
import cats.implicits._
|
||||
|
||||
object DTree {
|
||||
|
||||
// opaques WHEN
|
||||
type Feature = String
|
||||
type Value = String
|
||||
type Cls = String
|
||||
|
||||
case class TrainingData(values: Map[Feature, Value], cls: Cls)
|
||||
|
||||
type TestData = Map[Feature, Value]
|
||||
|
||||
// Base
|
||||
// def predict(data: TestData): Cls = "Died"
|
||||
|
||||
// Gendered
|
||||
def predictStatic(data: TestData): Cls =
|
||||
if(data("gender") == "female")
|
||||
"survived"
|
||||
else "died"
|
||||
|
||||
|
||||
sealed trait Tree
|
||||
case class Node(feature: Feature, children: Map[Value, Tree]) extends Tree
|
||||
case class Leaf(cls: Cls) extends Tree
|
||||
|
||||
val genderBased: Tree = Node(
|
||||
"gender", Map(
|
||||
"female" -> Leaf("survived"),
|
||||
"male" -> Leaf("died"),
|
||||
))
|
||||
|
||||
|
||||
def predict(data: TestData)(tree: Tree): Cls =
|
||||
tree match {
|
||||
case Leaf(cls) => cls
|
||||
case Node(feature, children) => predict(data)(children(data(feature)))
|
||||
}
|
||||
|
||||
val data = Map("gender" -> "female", "family size" -> "0", "ticket" -> "1")
|
||||
|
||||
predict(data)(genderBased) // true
|
||||
|
||||
|
||||
def entropy(classes: List[Cls]): Double = {
|
||||
val total = classes.size
|
||||
classes.groupBy(identity)
|
||||
.mapValues { group =>
|
||||
val prop = group.size / total
|
||||
prop * math.log(1.0 / prop)
|
||||
}.values.sum
|
||||
}
|
||||
|
||||
def bucketedEntropy(data: List[TrainingData], feature: Feature): Double = {
|
||||
val total = data.size
|
||||
val bucketed = data.groupBy(_.values(feature))
|
||||
.mapValues(_.map(_.cls))
|
||||
.toMap
|
||||
bucketed.values.map { classes =>
|
||||
val prop = classes.size / total
|
||||
prop * entropy(classes)
|
||||
}.sum
|
||||
}
|
||||
|
||||
def best(data: List[TrainingData], features: Set[Feature]): Feature = features.minBy(bucketedEntropy(data, _))
|
||||
|
||||
def mostCommonCls(data: List[TrainingData]): Cls = ???
|
||||
|
||||
def build(data: List[TrainingData], features: Set[Feature]): Tree = {
|
||||
if(features.nonEmpty) {
|
||||
val feature = best(data, features)
|
||||
val buckets = data.groupBy(_.values(feature))
|
||||
Node(feature, buckets.mapValues(build(_, features - feature)))
|
||||
} else {
|
||||
Leaf(mostCommonCls(data))
|
||||
}
|
||||
}
|
||||
|
||||
def withHKT {
|
||||
|
||||
sealed trait Tree[A]
|
||||
case class Node[A](feature: Feature, children: Map[Value, A]) extends Tree[A]
|
||||
case class Leaf[A](cls: Cls) extends Tree[A]
|
||||
|
||||
// import matryoshka._
|
||||
// import matryoshka.data.Fix
|
||||
// import matryoshka.implicits._
|
||||
|
||||
case class Fix[F[_]](unfix: F[Fix[F]])
|
||||
case class Cofree[F[_], A](head: A, tail: F[Cofree[F, A]]){
|
||||
def counit: A = head
|
||||
def map[B](f: A => B)(implicit ev: Functor[F]): Cofree[F, B] = Cofree(f(head), tail.map(_.map(f)))
|
||||
|
||||
/**
|
||||
* Coflatmap alters the value of the node based on its context, then recursively
|
||||
* alters its tail independently (which makes sense as it's the only thing Cofree[F, A] => B can do.
|
||||
*/
|
||||
def coflatMap[B](fa: Cofree[F, A] => B)(implicit ev: Functor[F]): Cofree[F, B] = {
|
||||
val b = fa(this)
|
||||
val fb = tail.map(_.coflatMap(fa))
|
||||
Cofree(b, fb)
|
||||
}
|
||||
}
|
||||
|
||||
implicit val treeFunctor: Functor[Tree] = new Functor[Tree] {
|
||||
def map[A, B](fa: Tree[A])(f: A => B): Tree[B] = fa match {
|
||||
case Node(name, children) => Node(name, children.mapValues(f))
|
||||
case Leaf(cls) => Leaf(cls)
|
||||
}
|
||||
}
|
||||
|
||||
val genderBased: Fix[Tree] =
|
||||
Fix(Node(
|
||||
"gender",
|
||||
Map(
|
||||
"female" -> Fix(Leaf[Fix[Tree]]("survived")),
|
||||
"male" -> Fix(Leaf[Fix[Tree]]("died"))
|
||||
)))
|
||||
|
||||
def build: ((List[TrainingData], Set[Feature])) => Tree[(List[TrainingData], Set[Feature])] = {
|
||||
case (data, features) =>
|
||||
if(features.nonEmpty) {
|
||||
val feature = best(data, features)
|
||||
val buckets = data.groupBy(_.values(feature))
|
||||
val next = buckets.mapValues { subset => (subset, features - feature) }
|
||||
Node(feature, next)
|
||||
} else {
|
||||
Leaf(mostCommonCls(data))
|
||||
}
|
||||
}
|
||||
|
||||
def explore(testData: TestData): Fix[Tree] => Cls Either Fix[Tree] =
|
||||
fix => fix.unfix match {
|
||||
case Leaf(cls) => Left(cls)
|
||||
case Node(feature, children) => Right(children.get(testData(feature)).get)
|
||||
}
|
||||
|
||||
// Anamorphism: Generalized unfold, builds structures
|
||||
def ana[F[_]: Functor, A](f: A => F[A])(a: A): Fix[F] =
|
||||
Fix( (f(a)).map(ana(f)) )
|
||||
|
||||
// Catamorphism: Generalized fold, tears structures down.
|
||||
def cata[F[_]: Functor, A](fa: F[A] => A)(f: Fix[F]): A = {
|
||||
fa(f.unfix.map(cata(fa)))
|
||||
}
|
||||
|
||||
// def hyloSimple[F[_] : Functor, A, B](f: F[B] => B)(g: A => F[A]): A => B
|
||||
def hyloSimple[F[_]: Functor, A, B](f: F[B] => B)(g: A => F[A])(a: A): B =
|
||||
cata(f)(ana(g)(a))
|
||||
|
||||
// A more powerful cata
|
||||
def para[F[_]: Functor, A](f: F[(Fix[F], A)] => A)(fa: Fix[F]): A =
|
||||
f(fa.unfix.map(x => (x, para(f)(x))))
|
||||
|
||||
// A more powerful ana
|
||||
def apo[F[_]: Functor, A](f: A => F[Either[Fix[F], A]])(a: A): Fix[F] = {
|
||||
Fix(f(a).map{
|
||||
case Right(a) => apo(f)(a)
|
||||
case Left(fix) => fix
|
||||
})
|
||||
}
|
||||
|
||||
// When we have cofree
|
||||
def histo[F[_]: Functor, A](f: F[Cofree[F, A]] => A)(fix: Fix[F]): A = {
|
||||
def toCofree(fix: Fix[F]): Cofree[F, A] =
|
||||
Cofree(histo(f)(fix), fix.unfix.map(toCofree))
|
||||
|
||||
f(fix.unfix.map(toCofree))
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -1,164 +0,0 @@
|
|||
package FiveStage
|
||||
import cats.data.Writer
|
||||
import cats._
|
||||
import cats.data.{ Op => _ }
|
||||
import cats.implicits._
|
||||
|
||||
import fileUtils.say
|
||||
|
||||
object DeletDis {
|
||||
|
||||
def delet = {
|
||||
|
||||
case class Fix[F[_]](unfix: F[Fix[F]])
|
||||
case class Cofree[F[_], A](head: A, tail: F[Cofree[F, A]]){
|
||||
def counit: A = head
|
||||
def map[B](f: A => B)(implicit ev: Functor[F]): Cofree[F, B] = Cofree(f(head), tail.map(_.map(f)))
|
||||
|
||||
/**
|
||||
* Coflatmap alters the value of the node based on its context, then recursively
|
||||
* alters its tail independently (which makes sense as it's the only thing Cofree[F, A] => B can do.
|
||||
*/
|
||||
def coflatMap[B](fa: Cofree[F, A] => B)(implicit ev: Functor[F]): Cofree[F, B] = {
|
||||
val b = fa(this)
|
||||
val fb = tail.map(_.coflatMap(fa))
|
||||
Cofree(b, fb)
|
||||
}
|
||||
}
|
||||
|
||||
// Anamorphism: Generalized unfold, builds structures
|
||||
def ana[F[_]: Functor, A](f: A => F[A])(a: A): Fix[F] =
|
||||
Fix( (f(a)).map(ana(f)) )
|
||||
|
||||
// Catamorphism: Generalized fold, tears structures down.
|
||||
def cata[F[_]: Functor, A](fa: F[A] => A)(f: Fix[F]): A = {
|
||||
fa(f.unfix.map(cata(fa)))
|
||||
}
|
||||
|
||||
// def hyloSimple[F[_] : Functor, A, B](f: F[B] => B)(g: A => F[A]): A => B
|
||||
def hylo[F[_]: Functor, A, B](f: F[B] => B)(g: A => F[A])(a: A): B =
|
||||
cata(f)(ana(g)(a))
|
||||
|
||||
// A more powerful cata
|
||||
def para[F[_]: Functor, A](f: F[(Fix[F], A)] => A)(fa: Fix[F]): A =
|
||||
f(fa.unfix.map(x => (x, para(f)(x))))
|
||||
|
||||
// A more powerful ana
|
||||
def apo[F[_]: Functor, A](f: A => F[Either[Fix[F], A]])(a: A): Fix[F] = {
|
||||
Fix(f(a).map{
|
||||
case Right(a) => apo(f)(a)
|
||||
case Left(fix) => fix
|
||||
})
|
||||
}
|
||||
|
||||
// When we have cofree
|
||||
def histo[F[_]: Functor, A](f: F[Cofree[F, A]] => A)(fix: Fix[F]): A = {
|
||||
def toCofree(fix: Fix[F]): Cofree[F, A] =
|
||||
Cofree(histo(f)(fix), fix.unfix.map(toCofree))
|
||||
|
||||
f(fix.unfix.map(toCofree))
|
||||
}
|
||||
|
||||
sealed trait StackR
|
||||
final case class DoneR(result: Int = 1) extends StackR
|
||||
final case class MoreR(stack: StackR, next: Int) extends StackR
|
||||
|
||||
def unfoldStackR(n: Int): StackR =
|
||||
if(n > 0) MoreR(unfoldStackR(n-1), n) else DoneR()
|
||||
|
||||
say(unfoldStackR(5))
|
||||
|
||||
sealed trait Stack[A]
|
||||
final case class Done[A](result: Int) extends Stack[A]
|
||||
final case class More[A](a: A, next: Int) extends Stack[A]
|
||||
|
||||
object Stack {
|
||||
implicit val stackFunctor: Functor[Stack] = new Functor[Stack] {
|
||||
def map[A, B](fa: Stack[A])(f: A => B): Stack[B] = fa match {
|
||||
case Done(result) => Done(result)
|
||||
case More(a, next) => More(f(a), next)
|
||||
}
|
||||
}
|
||||
|
||||
def done[A](result: Int = 1): Stack[A] = Done(result)
|
||||
def more[A](a: A, next: Int): Stack[A] = More(a, next)
|
||||
}
|
||||
|
||||
import Stack._
|
||||
|
||||
val stackCoalgebra: Int => Stack[Int] =
|
||||
n => if(n > 0) more(n - 1, n) else done()
|
||||
|
||||
say(ana(stackCoalgebra)(5))
|
||||
|
||||
val stackAlgebra: Stack[Int] => Int = {
|
||||
case Done(result) => result
|
||||
case More(acc, next) => acc * next
|
||||
}
|
||||
|
||||
say(cata(stackAlgebra)(ana(stackCoalgebra)(5)))
|
||||
say(hylo(stackAlgebra)(stackCoalgebra)(5))
|
||||
|
||||
|
||||
sealed trait Nat[A]
|
||||
final case class Zero[A]() extends Nat[A]
|
||||
final case class Succ[A](prev: A) extends Nat[A]
|
||||
|
||||
object Nat {
|
||||
implicit val natFunctor: Functor[Nat] = new Functor[Nat] {
|
||||
override def map[A, B](na: Nat[A])(f: A => B): Nat[B] =
|
||||
na match {
|
||||
case Zero() => Zero()
|
||||
case Succ(a) => Succ(f(a))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val natAlgebra: Nat[Int] => Int = {
|
||||
case Zero() => 1
|
||||
case Succ(n) => {
|
||||
say(s"nat alg succ $n")
|
||||
n + 1
|
||||
}
|
||||
}
|
||||
|
||||
val natAlgebraS: Nat[String] => String = {
|
||||
case Zero() => "N"
|
||||
case Succ(n) => n match {
|
||||
case "N" => "NI"
|
||||
case "NI" => "NIG"
|
||||
case "NIG" => "NIGG"
|
||||
case "NIGG" => "NIGGE"
|
||||
case "NIGGE" => "NIGGER :-"
|
||||
case s => s + "D"
|
||||
}
|
||||
}
|
||||
|
||||
val natCoalgebra: Int => Nat[Int] =
|
||||
n => if (n == 0) Zero() else Succ(n - 1)
|
||||
|
||||
val b = ana(natCoalgebra)(9)
|
||||
val c = cata(natAlgebraS)(b)
|
||||
say(c)
|
||||
|
||||
|
||||
val natAlgebraPara: Nat[(Fix[Nat], Int)] => Int = {
|
||||
case Zero() => 1
|
||||
case Succ((fix, acc)) => {
|
||||
say(s"nat para alg succ $fix, $acc")
|
||||
cata(natAlgebra)(fix) * acc
|
||||
}
|
||||
}
|
||||
|
||||
val build = ana(natCoalgebra)(_)
|
||||
say("built")
|
||||
val tear = para(natAlgebraPara)(_)
|
||||
say(tear(build(5)))
|
||||
// say(ana(natCoalgebra)(5))
|
||||
|
||||
val lastThreeSteps: Fix[Stack] = Fix(More(Fix(More(Fix(More(Fix(Done(1)),1)),2)),3))
|
||||
|
||||
val stackCoalgebraApo: Int => Stack[Either[Fix[Stack], Int]] =
|
||||
n => if(n > 3) more(n - 1, n).map(_.asRight) else lastThreeSteps.unfix.map(_.asLeft)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue