Skip to content

Commit

Permalink
ported tests for CpsLogic
Browse files Browse the repository at this point in the history
  • Loading branch information
rssh committed Dec 27, 2023
1 parent 42b08fb commit 7da139a
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 5 deletions.
6 changes: 6 additions & 0 deletions shared/src/test/scala/logic/CpsLogicMonad.scala
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,12 @@ extension [M[_],A](ma: M[A])(using m:CpsLogicMonad[M])

def |+|(mb: =>M[A]): M[A] =
m.mplus(ma,mb)

def ||(mb: =>M[A]): M[A] =
m.mplus(ma,mb)

def |(mb: =>M[A]): M[A] =
m.interleave(ma,mb)


transparent inline def guard[M[_]:CpsLogicMonad](p: =>Boolean)(using mc:CpsLogicMonadContext[M]): Unit =
Expand Down
110 changes: 108 additions & 2 deletions shared/src/test/scala/logic/LogicTTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,102 @@ class LogicTTest {

import LogicTTest.*

type LogicSKFKCB[A] = LogicT[ComputationBound,A]


@Test
def testNatCB():Unit = {

val cbNat = nats[[A] =>> LogicT[ComputationBound,A]]
val cbNat = nats[LogicSKFKCB]

val cb4 = cbNat.observeN(4)
assert(cb4.run(1.second) == Success(Seq(1,2,3,4)))

val cbOdd = odds[[A] =>> LogicT[ComputationBound,A]]
//val cbStream = cbNat

val cbOdds = odds[LogicSKFKCB]
val odds4 = cbOdds.observeN(4)
assert(odds4.run(1.second) == Success(Seq(1,3,5,7)))

val cbOdds2unfair = cbOdds || summon[CpsLogicMonad[LogicSKFKCB]].pure(2)

val cbOdds2fair = cbOdds | summon[CpsLogicMonad[LogicSKFKCB]].pure(2)

val odds2unfair4 = cbOdds2unfair.observeN(4)
assert(odds2unfair4.run(1.second) == Success(Seq(1,3,5,7)))

val odds2fair4 = cbOdds2fair.observeN(4)
val odds4fair2result = odds2fair4.run(1.second).get
assert(odds4fair2result.contains(1))
assert(odds4fair2result.contains(2))
assert(odds4fair2result.contains(3))
assert(odds4fair2result.contains(5))
assert(odds4fair2result.size == 4)
}

@Test
def testNatCbOnce(): Unit = {
val m = summon[CpsLogicMonad[LogicSKFKCB]]
val myOnce = m.once(m.pure(1))
val myOnce4 = myOnce.observeN(4)
assert(myOnce4.run(1.second) == Success(Seq(1)))
}

@Test
def testNatCbFlatMap0(): Unit = {
import cps.syntax.*
val m = summon[CpsLogicMonad[LogicSKFKCB]]
val cbOdds = odds[LogicSKFKCB]
val cnOddsFlatMapZero = cbOdds.flatMap { x => m.mzero[Int] }
// infinitie loop.
// we see this, but can't detect in compile time.
//val res4 = cnOddsFlatMapZero.observeN(4)
//assert(res4.run(1.second) == Success(Seq(2)))
}

@Test
def testOnceNat(): Unit = {
val m = summon[CpsLogicMonad[LogicSKFKCB]]
val myOnce = m.once(nats)
val myOnce4 = myOnce.observeN(4)
assert(myOnce4.run(1.second) == Success(Seq(1)))
}


@Test
def testNatCbFlatMap1(): Unit = {
import cps.syntax.*
val m = summon[CpsLogicMonad[LogicSKFKCB]]
val cbOddsOrTwo = oddsOrTwo[LogicSKFKCB]
val cnOddsOrTwoFlatMap = cbOddsOrTwo.flatMap{ x =>
if (x % 2 == 0) then m.pure(x) else m.mzero[Int]
}
val res4 = cnOddsOrTwoFlatMap.observeOne
assert(res4.run(1.second) == Success(Some(2)))
}



/*
@Test
def testNatCbOddsOrTwo(): Unit = {
val cbOddsOrTwo = oddsOrTwo[LogicSKFKCB]
val oddsOrTwo4 = cbOddsOrTwo.observeN(4)
println(s"oddsOrTwo4 = ${oddsOrTwo4.run(1.second)}")
oddsOrTwo4.run(1.second) match
case Success(v) =>
println(s"v=$v")
case Failure(ex) =>
ex.printStackTrace()
}
*/





}

Expand All @@ -36,6 +118,30 @@ object LogicTTest {
m.pure(1) |+| reify[M] { 2 + reflect(odds) }


def oddsOrTwoUnfair[M[_]](using m:CpsLogicMonad[M]) = odds |+| m.pure(2)

def oddsOrTwoFair[M[_]](using m: CpsLogicMonad[M]) = odds | m.pure(2)

def oddsOrTwo[M[_]](using m: CpsLogicMonad[M]) = {
import cps.syntax.*
for {
x <- oddsOrTwoFair
y <- if (x % 2 == 0) then m.once(m.pure(x)) else m.mzero[Int]
} yield {
println(s"y=$y")
y
}
}

def odds5down[M[_]](using m:CpsLogicMonad[M]) =
m.pure(5) |+| m.mzero |+| m.mzero |+| m.pure(3) |+| m.pure(1)


def yieldWords[M[_]:CpsLogicMonad](words: String*): M[String] =
yieldWordsList(words.toList)

def yieldWordsList[M[_]](words: List[String])(using m: CpsLogicMonad[M]): M[String] =
if (words.isEmpty) then m.mzero[String]
else m.pure(words.head) |+| reify[M] { reflect(yieldWordsList(words.tail)) }

}
2 changes: 1 addition & 1 deletion shared/src/test/scala/logic/QueensTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class QueensTest {
import QueensTest.*
val r = queens[LogicM](8).observeN(2)
// observer monad is identity monad here.
println(s"QueensTest:r=$r")
//println(s"QueensTest:r=$r")
assert(r.size == 2)
assert(QueensTest.isCorrect(r(0)))
assert(QueensTest.isCorrect(r(1)))
Expand Down
5 changes: 3 additions & 2 deletions shared/src/test/scala/logic/logict/LogicSKFK.scala
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ object LogicSKFK {
new SuccessContinuation[F,A,R] {
override def apply(ta: Try[A])(fk: =>F[R]): F[R] =
ta match
case Success(a) => sk(Success(f(a)))(fk)
case Success(a) =>
sk(Success(f(a)))(fk)
case Failure(ex) => sk(Failure(ex))(fk)
}
}(fk)
Expand Down Expand Up @@ -187,7 +188,7 @@ object LogicSKFK {
observerCpsMonad.error(ex)
case Failure(ex) =>
observerCpsMonad.error(ex)
})(zero)
})(zero)
}

}
Expand Down

0 comments on commit 7da139a

Please sign in to comment.