Skip to content

Commit 31504ce

Browse files
committed
chore: start importing the engine
1 parent 3220d4c commit 31504ce

File tree

9 files changed

+123
-7
lines changed

9 files changed

+123
-7
lines changed

src/main/scala/io/github/kelvindev15/prolog/core/Constant.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ object Constant:
1717
case _ => throw IllegalArgumentException("Cannot create a constant with the provided argument")
1818
trait Atom extends Constant with Struct:
1919
override val value: String
20+
val unquotedValue: String
2021
override val arity: Int = 0
2122
override val arguments: Seq[Term] = Seq()
2223
override val functor: Atom = this
@@ -26,6 +27,7 @@ object Constant:
2627
def apply(value: String): Atom = AtomImpl(removeQuotes(value))
2728
private case class AtomImpl(private val _value: String) extends Atom:
2829
override val value: String = quoteIfFunctorIsMalformed(_value)
30+
override val unquotedValue: String = _value
2931

3032
trait Numeric extends Constant:
3133
override val value: AnyVal

src/main/scala/io/github/kelvindev15/prolog/core/Prolog.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,4 @@ object Prolog:
1515
val CLAUSE: Atom = Atom(":-")
1616
val EMPTY_LIST: Atom = Atom("[]")
1717
val CONS: Atom = Atom(".")
18-
val TRUE: Atom = Atom("true")
19-
val FAIL: Atom = Atom("fail")
2018
val INDICATOR: Atom = Atom("/")

src/main/scala/io/github/kelvindev15/prolog/dsl/DSLExtensions.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package io.github.kelvindev15.prolog.dsl
22

33
import io.github.kelvindev15.prolog.core.Constant.Atom
44
import io.github.kelvindev15.prolog.core.Struct.Rule
5-
import io.github.kelvindev15.prolog.core.{Goals, PrologList, Struct, Term}
5+
import io.github.kelvindev15.prolog.core.{Goals, Struct, Term}
66

77
import scala.annotation.targetName
88

src/main/scala/io/github/kelvindev15/prolog/dsl/DSLPrologBuiltins.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import scala.annotation.targetName
1010
enum AssociativitySpec extends Atom:
1111
case fx, fy, xf, xfx, xfy, yfx, yfy
1212
override val value: String = toString
13+
override val unquotedValue: String = value
1314

1415
trait DSLPrologBuiltins:
1516
dsl: PrologDSL =>

src/main/scala/io/github/kelvindev15/prolog/dsl/DeclarativeDSL.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package io.github.kelvindev15.prolog.dsl
22

33
import io.github.kelvindev15.prolog.PrologProgram
4-
import io.github.kelvindev15.prolog.core.{Struct, Term}
54
import io.github.kelvindev15.prolog.core.Struct.{Clause, Directive, Fact, Rule}
65
import io.github.kelvindev15.prolog.core.Theory.Theory
6+
import io.github.kelvindev15.prolog.core.{Struct, Term}
77
import io.github.kelvindev15.prolog.dsl.DeclarativeDSL.{MutableDynamicTheoryWrapper, MutableTheoryWrapper}
88

99

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package io.github.kelvindev15.prolog.engine
2+
3+
import io.github.kelvindev15.prolog.PrologProgram
4+
import io.github.kelvindev15.prolog.core.Term
5+
import io.github.kelvindev15.prolog.core.Theory.Theory
6+
import io.github.kelvindev15.prolog.engine.PrologEngine.Solution
7+
import io.github.kelvindev15.prolog.engine.visitors.TuPKtTermVisitor
8+
import it.unibo.tuprolog.solve.channel.{InputStore, OutputStore}
9+
import it.unibo.tuprolog.solve.classic.ClassicSolverFactory
10+
import it.unibo.tuprolog.solve.flags.FlagStore
11+
import it.unibo.tuprolog.unify.Unificator
12+
import it.unibo.tuprolog.solve.library.Runtime
13+
import it.unibo.tuprolog.theory.Theory as KTheory
14+
import it.unibo.tuprolog.core.{Clause as KClause, Struct as KStruct, Term as KTerm}
15+
import it.unibo.tuprolog.solve.Solver as KSolver
16+
17+
import scala.jdk.CollectionConverters.*
18+
19+
trait PrologEngine extends Function[PrologProgram, Seq[Solution]]:
20+
???
21+
22+
object PrologEngine:
23+
trait Solution
24+
25+
object Solver:
26+
private val visitor = TuPKtTermVisitor()
27+
given Conversion[Term, KTerm] = _.accept(visitor)
28+
given Conversion[KTerm, KClause] = _.asClause()
29+
given Conversion[KTerm, KStruct] = _.asStruct()
30+
given Conversion[Theory, KTheory] with
31+
override def apply(theory: Theory): KTheory = KTheory.of(theory.map(_.asClause())*)
32+
33+
private def solverOf(staticTheory: Theory, dynamicTheory: Theory): KSolver =
34+
ClassicSolverFactory.INSTANCE.solverOf(
35+
Unificator.getDefault,
36+
Runtime.empty(),
37+
FlagStore.DEFAULT,
38+
staticTheory,
39+
dynamicTheory,
40+
InputStore.fromStandard(),
41+
OutputStore.fromStandard()
42+
)
43+
44+
def solve(program: PrologProgram): Solution =
45+
val solver = solverOf(program.dynamicTheory, program.staticTheory)
46+
program.goal.foreach { t =>
47+
val goal: KStruct = Some(t.asStruct()).get
48+
val sol = solver.solve(goal)
49+
sol.iterator().forEachRemaining(s => {
50+
println(s)
51+
})
52+
}
53+
new Solution {}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package io.github.kelvindev15.prolog.engine.visitors
2+
3+
import io.github.kelvindev15.prolog.core.Constant.Atom
4+
import io.github.kelvindev15.prolog.core.Struct.{Clause, Directive, Fact, Rule}
5+
import io.github.kelvindev15.prolog.core.{Constant, Struct, Variable}
6+
import io.github.kelvindev15.prolog.utils.TermVisitor
7+
import it.unibo.tuprolog.core.{
8+
Term as KTerm,
9+
Atom as KAtom,
10+
Numeric as KNumeric,
11+
Var as KVar,
12+
Struct as KStruct,
13+
Fact as KFact,
14+
Rule as KRule,
15+
Directive as KDirective,
16+
}
17+
18+
class TuPKtTermVisitor extends TermVisitor[KTerm]:
19+
override def visit(atom: Atom): KTerm = KAtom.of(atom.unquotedValue)
20+
override def visit(numeric: Constant.Numeric): KTerm = KNumeric.of(numeric.value.asInstanceOf[Double])
21+
override def visit(struct: Struct): KTerm = struct match
22+
case clause: Clause => super.visit(clause)
23+
case _ => KStruct.of(struct.functor.unquotedValue, struct.arguments.map(this.visit)*)
24+
override def visit(fact: Fact): KTerm = fact.head.map(h => KFact.of(h.accept(this).asStruct())).get
25+
override def visit(rule: Rule): KTerm =
26+
rule.head.map(h => KRule.of(h.accept(this).asStruct(), rule.body.accept(this))).get
27+
override def visit(directive: Directive): KTerm = KDirective.of(directive.body.accept(this))
28+
override def visit(variable: Variable): KTerm = KVar.of(variable.name)
29+
Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,29 @@
11
package io.github.kelvindev15.prolog.utils
22

3-
import io.github.kelvindev15.prolog.core.{Constant, Struct, Variable}
3+
import io.github.kelvindev15.prolog.core.{Constant, Struct, Term, Variable}
44
import io.github.kelvindev15.prolog.core.Constant.{Atom, Numeric}
55
import io.github.kelvindev15.prolog.core.RecursiveStruct.BinaryRecursiveStruct
6-
import io.github.kelvindev15.prolog.core.Struct.{Fact, Rule}
6+
import io.github.kelvindev15.prolog.core.Struct.{Clause, Directive, Fact, Rule}
77

88
trait TermVisitor[T]:
9-
def visit(constant: Constant): T = throw NotImplementedError()
9+
def visit(term: Term): T = term match
10+
case constant: Constant => visit(constant)
11+
case variable: Variable => visit(variable)
12+
case struct: Struct => visit(struct)
13+
def visit(constant: Constant): T = constant match
14+
case atom: Atom => visit(atom)
15+
case numeric: Numeric => visit(numeric)
1016
def visit(atom: Atom): T = throw NotImplementedError()
1117
def visit(numeric: Numeric): T = throw NotImplementedError()
1218
def visit(variable: Variable): T = throw NotImplementedError()
1319
def visit(struct: Struct): T = throw NotImplementedError()
20+
def visit(clause: Clause): T = clause match
21+
case fact: Fact => visit(fact)
22+
case rule: Rule => visit(rule)
23+
case directive: Directive => visit(directive)
1424
def visit(rule: Rule): T = throw NotImplementedError()
1525
def visit(fact: Fact): T = throw NotImplementedError()
26+
def visit(directive: Directive): T = throw NotImplementedError()
27+
1628
def visit(binaryRecursiveStruct: BinaryRecursiveStruct): T = throw NotImplementedError()
1729

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package io.github.kelvindev15.engine
2+
3+
import io.github.kelvindev15.prolog.dsl.{DeclarativeDSL, PrologDSL}
4+
import io.github.kelvindev15.prolog.engine.PrologEngine.Solution
5+
import io.github.kelvindev15.prolog.engine.Solver
6+
import org.scalatest.flatspec.AnyFlatSpec
7+
import org.scalatest.matchers.should.Matchers
8+
9+
class TestPrologEngine extends AnyFlatSpec with Matchers with PrologDSL with DeclarativeDSL:
10+
11+
"A prolog with no solution" should "return a single NO answer" in:
12+
val solution = Solver.solve {
13+
prolog {
14+
staticTheory {
15+
clause { "father"("mala", "paga") }
16+
clause { "father"("mala", "kel") }
17+
}
18+
solve { "father"("mala", X) }
19+
}
20+
}
21+
solution shouldBe a [Solution]

0 commit comments

Comments
 (0)