Arithmetic preprocessing

This commit is contained in:
Tibo De Peuter 2025-04-28 12:20:03 +02:00
parent 174855d7a3
commit 32165a90f5
Signed by: tdpeuter
GPG key ID: 38297DE43F75FFE2
3 changed files with 442 additions and 124 deletions

View file

@ -1,24 +1,13 @@
package interpreter
import io.Logger
import prolog.ast.arithmetic.Expression
import prolog.ast.logic.Clause
import prolog.ast.logic.Fact
import prolog.ast.logic.LogicOperand
import prolog.ast.logic.Rule
import prolog.ast.terms.Atom
import prolog.ast.terms.Body
import prolog.ast.terms.Goal
import prolog.ast.terms.Head
import prolog.ast.terms.Structure
import prolog.ast.terms.Term
import prolog.builtins.Conjunction
import prolog.builtins.Cut
import prolog.builtins.Disjunction
import prolog.builtins.Fail
import prolog.builtins.False
import prolog.builtins.Not
import prolog.builtins.Query
import prolog.builtins.True
import prolog.ast.terms.*
import prolog.builtins.*
/**
* Preprocessor for Prolog
@ -45,12 +34,14 @@ open class Preprocessor {
is Fact -> {
Fact(preprocess(clause.head) as Head)
}
is Rule -> {
Rule(
preprocess(clause.head) as Head,
preprocess(clause.body as Term) as Body
)
}
else -> clause
}
}
@ -65,23 +56,70 @@ open class Preprocessor {
Structure(Atom("fail"), emptyList()) -> Fail
Atom("!") -> Cut()
Structure(Atom("!"), emptyList()) -> Cut()
else -> {
is Structure -> {
// Preprocess the arguments first to recognize builtins
val args = term.arguments.map { preprocess(it) }
when {
term is Structure && term.functor == ",/2" -> {
val args = term.arguments.map { preprocess(it) }
// TODO Remove hardcoding by storing the functors as constants in operators?
// Logic
term.functor == ",/2" -> {
Conjunction(args[0] as LogicOperand, args[1] as LogicOperand)
}
term is Structure && term.functor == ";/2" -> {
val args = term.arguments.map { preprocess(it) }
term.functor == ";/2" -> {
Disjunction(args[0] as LogicOperand, args[1] as LogicOperand)
}
term is Structure && term.functor == "\\+/1" -> {
val args = term.arguments.map { preprocess(it) }
term.functor == "\\+/1" -> {
Not(args[0] as Goal)
}
// Arithmetic
term.functor == "=\\=/2" && args.all { it is Expression } -> {
EvaluatesToDifferent(args[0] as Expression, args[1] as Expression)
}
term.functor == "=:=/2" && args.all { it is Expression } -> {
EvaluatesTo(args[0] as Expression, args[1] as Expression)
}
term.functor == "is/2" && args.all { it is Expression } -> {
Is(args[0] as Expression, args[1] as Expression)
}
term.functor == "-/1" && args.all { it is Expression } -> {
Negate(args[0] as Expression)
}
term.functor == "-/2" && args.all { it is Expression } -> {
Subtract(args[0] as Expression, args[1] as Expression)
}
term.functor == "+/1" && args.all { it is Expression } -> {
Positive(args[0] as Expression)
}
term.functor == "+/2" && args.all { it is Expression } -> {
Add(args[0] as Expression, args[1] as Expression)
}
term.functor == "*/2" && args.all { it is Expression } -> {
Multiply(args[0] as Expression, args[1] as Expression)
}
term.functor == "//2" && args.all { it is Expression } -> {
Divide(args[0] as Expression, args[1] as Expression)
}
term.functor == "between/3" && args.all { it is Expression } -> {
Between(args[0] as Expression, args[1] as Expression, args[2] as Expression)
}
else -> term
}
}
else -> term
}
if (prepped != term || prepped::class != term::class) {