Checkpoint
This commit is contained in:
parent
973365e2ec
commit
3724ac72f9
13 changed files with 659 additions and 29 deletions
|
@ -7,6 +7,9 @@ import prolog.ast.arithmetic.Integer
|
|||
import prolog.ast.terms.*
|
||||
import prolog.ast.logic.Clause
|
||||
import prolog.logic.*
|
||||
import prolog.ast.lists.List
|
||||
import prolog.ast.lists.List.Empty
|
||||
import prolog.ast.lists.List.Cons
|
||||
|
||||
/**
|
||||
* [True] when [Term] is a term with [Functor] Name/Arity.
|
||||
|
@ -66,15 +69,13 @@ class Arg(private val arg: Term, private val term: Term, private val value: Term
|
|||
// Value will be unified with the successive arguments of term.
|
||||
// On successful unification, arg is unified with the argument number.
|
||||
// Backtracking yields alternative solutions.
|
||||
var count = 0
|
||||
for (argument in t.arguments) {
|
||||
for ((count, argument) in t.arguments.withIndex()) {
|
||||
unifyLazy(value, argument, subs).forEach { result ->
|
||||
result.map {
|
||||
val sub = arg to Integer(count + 1)
|
||||
yield(Result.success(it + sub))
|
||||
}
|
||||
}
|
||||
count++
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -94,6 +95,12 @@ class Arg(private val arg: Term, private val term: Term, private val value: Term
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun applySubstitution(subs: Substitutions): Arg = Arg(
|
||||
arg.applySubstitution(subs),
|
||||
term.applySubstitution(subs),
|
||||
value.applySubstitution(subs)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -118,11 +125,14 @@ class ClauseOp(private val head: Head, private val body: Body) :
|
|||
val clauseHead = clause.head
|
||||
val clauseBody = clause.body
|
||||
|
||||
val appliedHead = applySubstitution(head, subs)
|
||||
val appliedBody = applySubstitution(body, subs)
|
||||
|
||||
// Unify the head of the clause with the head of the goal
|
||||
unifyLazy(clauseHead, head, subs).forEach { result ->
|
||||
unifyLazy(clauseHead, appliedHead, subs).forEach { result ->
|
||||
result.map { headSubs ->
|
||||
// Unify the body of the clause with the body of the goal
|
||||
unifyLazy(clauseBody, body, headSubs).forEach { bodyResult ->
|
||||
unifyLazy(clauseBody, appliedBody, headSubs).forEach { bodyResult ->
|
||||
bodyResult.map { bodySubs ->
|
||||
// Combine the substitutions from the head and body
|
||||
val combinedSubs = headSubs + bodySubs
|
||||
|
@ -136,6 +146,11 @@ class ClauseOp(private val head: Head, private val body: Body) :
|
|||
yield(Result.success(emptyMap()))
|
||||
}
|
||||
}
|
||||
|
||||
override fun applySubstitution(subs: Substitutions): ClauseOp = ClauseOp(
|
||||
head.applySubstitution(subs) as Head,
|
||||
body.applySubstitution(subs) as Body
|
||||
)
|
||||
}
|
||||
|
||||
class AtomicOp(private val term: Term) : Operator(Atom("atomic"), null, term) {
|
||||
|
@ -146,6 +161,8 @@ class AtomicOp(private val term: Term) : Operator(Atom("atomic"), null, term) {
|
|||
emptySequence()
|
||||
}
|
||||
}
|
||||
|
||||
override fun applySubstitution(subs: Substitutions): AtomicOp = AtomicOp(term.applySubstitution(subs))
|
||||
}
|
||||
|
||||
class CompoundOp(private val term: Term) : Operator(Atom("compound"), null, term) {
|
||||
|
@ -156,4 +173,75 @@ class CompoundOp(private val term: Term) : Operator(Atom("compound"), null, term
|
|||
emptySequence()
|
||||
}
|
||||
}
|
||||
|
||||
override fun applySubstitution(subs: Substitutions): CompoundOp = CompoundOp(term.applySubstitution(subs))
|
||||
}
|
||||
|
||||
open class Univ(private val term: Term, private val list: Term) : Operator(Atom("=.."), term, list) {
|
||||
override fun satisfy(subs: Substitutions): Answers {
|
||||
return when {
|
||||
nonvariable(term, subs) && nonvariable(list, subs) -> {
|
||||
val t = applySubstitution(term, subs)
|
||||
val l = applySubstitution(list, subs) as List
|
||||
unifyLazy(t, listToTerm(l), subs)
|
||||
}
|
||||
|
||||
variable(term, subs) && nonvariable(list, subs) -> {
|
||||
val l = applySubstitution(list, subs) as List
|
||||
val t = listToTerm(l)
|
||||
unifyLazy(term, t, subs)
|
||||
}
|
||||
|
||||
nonvariable(term, subs) && variable(list, subs) -> {
|
||||
val t = applySubstitution(term, subs)
|
||||
val l = termToList(t)
|
||||
unifyLazy(l, list, subs)
|
||||
}
|
||||
|
||||
else -> throw Exception("Arguments are not sufficiently instantiated")
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun listToTerm(list: List): Term {
|
||||
return when {
|
||||
list.size.value == 1 -> list.head
|
||||
|
||||
list.size.value > 1 -> {
|
||||
val head = list.head
|
||||
val arguments = mutableListOf<Term>()
|
||||
var tail: List? = list.tail
|
||||
while (tail != null && tail !is Empty) {
|
||||
arguments.add(tail.head)
|
||||
tail = tail.tail
|
||||
}
|
||||
Structure(head as Atom, arguments)
|
||||
}
|
||||
|
||||
else -> throw IllegalStateException("List is empty")
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun termToList(term: Term): List {
|
||||
return when (term) {
|
||||
is Atom -> Cons(term, Empty)
|
||||
|
||||
is Structure -> {
|
||||
val head = term.functor.name
|
||||
val arguments = term.arguments
|
||||
// Construct the list by iterating over the arguments in reverse
|
||||
var tail: List = Empty
|
||||
for (i in arguments.size - 1 downTo 0) {
|
||||
tail = Cons(arguments[i], tail)
|
||||
}
|
||||
return Cons(head, tail)
|
||||
}
|
||||
|
||||
else -> throw IllegalStateException("Term is not a valid structure")
|
||||
}
|
||||
}
|
||||
|
||||
override fun applySubstitution(subs: Substitutions): Univ = Univ(
|
||||
term.applySubstitution(subs),
|
||||
list.applySubstitution(subs)
|
||||
)
|
||||
}
|
||||
|
|
Reference in a new issue