IO Operators
This commit is contained in:
parent
b9f419a59d
commit
82a8fccf87
22 changed files with 450 additions and 199 deletions
|
@ -14,21 +14,24 @@ import prolog.ast.arithmetic.Float
|
|||
// Apply substitutions to a term
|
||||
fun applySubstitution(term: Term, subs: Substitutions): Term = when {
|
||||
variable(term, emptyMap()) -> subs[(term as Variable)] ?: term
|
||||
atomic(term, subs) -> term
|
||||
atomic(term, subs) -> term
|
||||
compound(term, subs) -> {
|
||||
val structure = term as Structure
|
||||
Structure(structure.name, structure.arguments.map { applySubstitution(it, subs) })
|
||||
}
|
||||
|
||||
else -> term
|
||||
}
|
||||
|
||||
//TODO Combine with the other applySubstitution function
|
||||
fun applySubstitution(expr: Expression, subs: Substitutions): Expression = when {
|
||||
variable(expr, subs) -> applySubstitution(expr as Term, subs) as Expression
|
||||
atomic(expr, subs) -> expr
|
||||
atomic(expr, subs) -> expr
|
||||
expr is LogicOperator -> {
|
||||
expr.arguments = expr.arguments.map { applySubstitution(it, subs) }
|
||||
expr
|
||||
}
|
||||
|
||||
else -> expr
|
||||
}
|
||||
|
||||
|
@ -40,6 +43,7 @@ private fun occurs(variable: Variable, term: Term, subs: Substitutions): Boolean
|
|||
val structure = term as Structure
|
||||
structure.arguments.any { occurs(variable, it, subs) }
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
|
||||
|
@ -56,12 +60,14 @@ fun unifyLazy(term1: Term, term2: Term, subs: Substitutions): Answers = sequence
|
|||
yield(Result.success(subs + (variable to t2)))
|
||||
}
|
||||
}
|
||||
|
||||
variable(t2, subs) -> {
|
||||
val variable = t2 as Variable
|
||||
if (!occurs(variable, t1, subs)) {
|
||||
yield(Result.success(subs + (variable to t1)))
|
||||
}
|
||||
}
|
||||
|
||||
compound(t1, subs) && compound(t2, subs) -> {
|
||||
val structure1 = t1 as Structure
|
||||
val structure2 = t2 as Structure
|
||||
|
@ -75,14 +81,17 @@ fun unifyLazy(term1: Term, term2: Term, subs: Substitutions): Answers = sequence
|
|||
}
|
||||
// Combine the results of all unifications
|
||||
val combinedResults = results.reduce { acc, result ->
|
||||
acc.flatMap { a -> result.map { b ->
|
||||
if (a.isSuccess && b.isSuccess) a.getOrThrow() + b.getOrThrow() else emptyMap()
|
||||
} }.map { Result.success(it) }
|
||||
acc.flatMap { a ->
|
||||
result.map { b ->
|
||||
if (a.isSuccess && b.isSuccess) a.getOrThrow() + b.getOrThrow() else emptyMap()
|
||||
}
|
||||
}.map { Result.success(it) }
|
||||
}
|
||||
yieldAll(combinedResults)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
@ -122,37 +131,40 @@ fun compare(term1: Term, term2: Term, subs: Substitutions): Int {
|
|||
return when (t1) {
|
||||
is Variable -> {
|
||||
when (t2) {
|
||||
is Variable -> t1.name.compareTo(t2.name)
|
||||
is Variable -> t1.name.compareTo(t2.name)
|
||||
is Number -> -1
|
||||
is Atom -> -1
|
||||
is Atom -> -1
|
||||
is Structure -> -1
|
||||
else -> throw IllegalArgumentException("Cannot compare $t1 with $t2")
|
||||
}
|
||||
}
|
||||
|
||||
is Number -> {
|
||||
when (t2) {
|
||||
is Variable -> 1
|
||||
is Integer -> (t1.value as Int).compareTo(t2.value)
|
||||
is Float -> (t1.value as kotlin.Float).compareTo(t2.value)
|
||||
is Atom -> -1
|
||||
is Variable -> 1
|
||||
is Integer -> (t1.value as Int).compareTo(t2.value)
|
||||
is Float -> (t1.value as kotlin.Float).compareTo(t2.value)
|
||||
is Atom -> -1
|
||||
is Structure -> -1
|
||||
else -> throw IllegalArgumentException("Cannot compare $t1 with $t2")
|
||||
}
|
||||
}
|
||||
|
||||
is Atom -> {
|
||||
when (t2) {
|
||||
is Variable -> 1
|
||||
is Variable -> 1
|
||||
is Number -> 1
|
||||
is Atom -> t1.name.compareTo(t2.name)
|
||||
is Atom -> t1.name.compareTo(t2.name)
|
||||
is Structure -> -1
|
||||
else -> throw IllegalArgumentException("Cannot compare $t1 with $t2")
|
||||
}
|
||||
}
|
||||
|
||||
is Structure -> {
|
||||
when (t2) {
|
||||
is Variable -> 1
|
||||
is Number -> 1
|
||||
is Atom -> 1
|
||||
is Atom -> 1
|
||||
is Structure -> {
|
||||
val arityComparison = t1.arguments.size.compareTo(t2.arguments.size)
|
||||
if (arityComparison != 0) return arityComparison
|
||||
|
@ -164,9 +176,11 @@ fun compare(term1: Term, term2: Term, subs: Substitutions): Int {
|
|||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
else -> throw IllegalArgumentException("Cannot compare $t1 with $t2")
|
||||
}
|
||||
}
|
||||
|
||||
else -> throw IllegalArgumentException("Cannot compare $t1 with $t2")
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue