Checkpoint
This commit is contained in:
parent
5bfa1691dd
commit
a85169dced
27 changed files with 377 additions and 250 deletions
|
@ -120,7 +120,8 @@ class Bar(leftOperand: LogicOperand, rightOperand: LogicOperand) : Disjunction(l
|
|||
class Not(private val goal: Goal) : LogicOperator(Atom("\\+"), rightOperand = goal) {
|
||||
override fun satisfy(subs: Substitutions): Answers {
|
||||
// If the goal can be proven, return an empty sequence
|
||||
if (goal.satisfy(subs).toList().isNotEmpty()) {
|
||||
val goalResults = goal.satisfy(subs).iterator()
|
||||
if (goalResults.hasNext()) {
|
||||
return emptySequence()
|
||||
}
|
||||
// If the goal cannot be proven, return a sequence with an empty map
|
||||
|
|
|
@ -6,14 +6,44 @@ import prolog.ast.logic.Clause
|
|||
import prolog.ast.terms.Atom
|
||||
import prolog.ast.terms.Structure
|
||||
import prolog.ast.logic.Predicate
|
||||
import prolog.Program
|
||||
import prolog.ast.Database.Program
|
||||
import prolog.ast.terms.Functor
|
||||
import prolog.ast.terms.Term
|
||||
import prolog.ast.logic.Fact
|
||||
import prolog.ast.Database
|
||||
import prolog.ast.terms.Body
|
||||
import prolog.ast.terms.Goal
|
||||
import prolog.ast.terms.Operator
|
||||
import prolog.logic.applySubstitution
|
||||
import prolog.logic.unifyLazy
|
||||
|
||||
/**
|
||||
* (Make) the [Predicate] with the corresponding [Functor] dynamic.
|
||||
*/
|
||||
class Dynamic(private val dynamicFunctor: Functor): Goal(), Body {
|
||||
override val functor: Functor = "dynamic/1"
|
||||
|
||||
override fun satisfy(subs: Substitutions): Answers {
|
||||
val predicate = Program.db.predicates[dynamicFunctor]
|
||||
if (predicate == null) {
|
||||
return sequenceOf(Result.failure(Exception("Predicate $dynamicFunctor not found")))
|
||||
}
|
||||
|
||||
predicate.dynamic = true
|
||||
return sequenceOf(Result.success(emptyMap()))
|
||||
}
|
||||
|
||||
override fun toString(): String = "dynamic $dynamicFunctor"
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is Dynamic) return false
|
||||
return dynamicFunctor == other.dynamicFunctor
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = super.hashCode()
|
||||
}
|
||||
|
||||
class Assert(clause: Clause) : AssertZ(clause) {
|
||||
override val functor: Functor = "assert/1"
|
||||
}
|
||||
|
@ -24,7 +54,8 @@ class Assert(clause: Clause) : AssertZ(clause) {
|
|||
class AssertA(val clause: Clause) : Operator(Atom("asserta"), null, clause) {
|
||||
override fun satisfy(subs: Substitutions): Answers {
|
||||
// Add clause to the program
|
||||
Program.load(listOf(clause), 0)
|
||||
val evaluatedClause = applySubstitution(clause, subs) as Clause
|
||||
Program.load(listOf(evaluatedClause), 0)
|
||||
|
||||
return sequenceOf(Result.success(emptyMap()))
|
||||
}
|
||||
|
@ -36,7 +67,8 @@ class AssertA(val clause: Clause) : Operator(Atom("asserta"), null, clause) {
|
|||
open class AssertZ(val clause: Clause) : Operator(Atom("assertz"), null, clause) {
|
||||
override fun satisfy(subs: Substitutions): Answers {
|
||||
// Add clause to the program
|
||||
Program.load(listOf(clause))
|
||||
val evaluatedClause = applySubstitution(clause, subs) as Clause
|
||||
Program.load(listOf(evaluatedClause))
|
||||
|
||||
return sequenceOf(Result.success(emptyMap()))
|
||||
}
|
||||
|
@ -58,26 +90,24 @@ class Retract(val term: Term) : Operator(Atom("retract"), null, term) {
|
|||
|
||||
val functorName = term.functor
|
||||
|
||||
Program.databases
|
||||
.filter { it.predicates.containsKey(functorName) }
|
||||
.mapNotNull { it.predicates[functorName] }
|
||||
.map { predicate ->
|
||||
val clausesIterator = predicate.clauses.iterator()
|
||||
while (clausesIterator.hasNext()) {
|
||||
val clause = clausesIterator.next()
|
||||
unifyLazy(term, clause.head, subs).forEach { unifyResult ->
|
||||
unifyResult.fold(
|
||||
onSuccess = { substitutions ->
|
||||
// If unification is successful, remove the clause
|
||||
yield(Result.success(substitutions))
|
||||
clausesIterator.remove()
|
||||
},
|
||||
onFailure = {
|
||||
// If unification fails, do nothing
|
||||
}
|
||||
)
|
||||
val predicate = Program.db.predicates[functorName]
|
||||
if (predicate == null) {
|
||||
return@sequence
|
||||
}
|
||||
|
||||
predicate.clauses.toList().forEach { clause ->
|
||||
unifyLazy(term, clause.head, subs).forEach { unifyResult ->
|
||||
unifyResult.fold(
|
||||
onSuccess = { substitutions ->
|
||||
// If unification is successful, remove the clause
|
||||
predicate.clauses.remove(clause)
|
||||
yield(Result.success(substitutions))
|
||||
},
|
||||
onFailure = {
|
||||
// If unification fails, do nothing
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import io.Logger
|
|||
import io.Terminal
|
||||
import parser.ReplParser
|
||||
import prolog.Answers
|
||||
import prolog.Program
|
||||
import prolog.ast.Database.Program
|
||||
import prolog.Substitutions
|
||||
import prolog.ast.logic.Satisfiable
|
||||
import prolog.ast.terms.Atom
|
||||
|
@ -26,6 +26,8 @@ class Write(private val term: Term) : Operator(Atom("write"), null, term), Satis
|
|||
|
||||
return sequenceOf(Result.success(emptyMap()))
|
||||
}
|
||||
|
||||
override fun toString(): String = "write($term)"
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,6 +8,7 @@ import prolog.ast.logic.LogicOperator
|
|||
|
||||
class Initialization(val goal: LogicOperand) : LogicOperator(Atom(":-"), null, goal) {
|
||||
override fun satisfy(subs: Substitutions): Answers = goal.satisfy(subs).take(1)
|
||||
override fun toString(): String = goal.toString()
|
||||
}
|
||||
|
||||
class Query(val query: LogicOperand) : LogicOperator(Atom("?-"), null, query) {
|
||||
|
|
Reference in a new issue