Skip to content

Commit 4ff3a80

Browse files
committed
test: Multiple solution from engine
1 parent 150ec0e commit 4ff3a80

File tree

3 files changed

+29
-3
lines changed

3 files changed

+29
-3
lines changed

src/main/scala/io/github/kelvindev15/prolog/engine/Solver.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ trait Solver:
1414

1515
object Solver:
1616
type Substitution = Map[Variable, Term]
17+
object Substitution:
18+
def apply(substitutions: (Variable, Term)*): Substitution = Map(substitutions*)
1719
enum Solution:
1820
case Yes(query: Struct, substitution: Substitution)
1921
case No(query: Struct)
@@ -23,3 +25,6 @@ object Solver:
2325

2426
def solve(using solver: Solver = tuPrologSolver())(prologProgram: PrologProgram): Iterator[Solution] =
2527
solver solve prologProgram
28+
29+
def lazySolve(using solver: Solver = tuPrologSolver())(prologProgram: PrologProgram): LazyList[Solution] =
30+
solver lazySolve prologProgram

src/test/scala/io/github/kelvindev15/engine/TestPrologEngine.scala

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,16 @@ class TestPrologEngine extends AnyFlatSpec with Matchers with TestUtils with Pro
4242

4343
"The goal 'X = 2, Y = 3, 5 is X + Y'" should "give a Yes solution" in:
4444
expectOne[Solution.Yes]:
45-
Solver solve (PrologProgram.emptyTheory withGoal &&(X `=` 2, Y `=` 3, 5 is X + Y))
45+
Solver solve (PrologProgram.emptyTheory withGoal &&(X `=` 2, Y `=` 3, 5 is X + Y))
46+
47+
"All solution" should "be returned by the engine" in:
48+
val fruit = "fruit"
49+
val fruits = Seq("banana", "orange", "apple")
50+
val query = fruit(X)
51+
Solver lazySolve {
52+
prolog:
53+
staticTheory:
54+
for f <- fruits do clause(fruit(f))
55+
goal:
56+
query
57+
} expectSolutionsIn fruits.map(e => query.yes(X -> e))

src/test/scala/io/github/kelvindev15/engine/utils/TestUtils.scala

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package io.github.kelvindev15.engine.utils
22

3-
import io.github.kelvindev15.prolog.engine.Solver.Solution
3+
import io.github.kelvindev15.prolog.core.{Struct, Term, Variable}
4+
import io.github.kelvindev15.prolog.engine.Solver.Solution.Yes
5+
import io.github.kelvindev15.prolog.engine.Solver.{Solution, Substitution}
46
import org.scalatest.matchers.should.Matchers
57

68
import scala.reflect.ClassTag
@@ -14,4 +16,11 @@ trait TestUtils:
1416
def expectOne[T <: Solution](using tag: ClassTag[T])(solution: Iterator[Solution]): Unit =
1517
expect[T](solution)
1618
solution.hasNext shouldBe false
17-
19+
20+
extension(solutions: Iterable[Solution])
21+
def expectSolutionsIn(expectedSolutions: Iterable[Solution]): Unit =
22+
solutions should contain allElementsOf expectedSolutions.to(LazyList)
23+
24+
extension(query: Struct)
25+
def yes(substitutions: (Variable, Term)*): Yes = Yes(query, Substitution(substitutions*))
26+
def no: Solution.No = Solution.No(query)

0 commit comments

Comments
 (0)