package prolog.ast.arithmetic

import prolog.Answers
import prolog.Substitutions
import prolog.ast.logic.LogicOperand
import prolog.ast.terms.Body

data class Integer(override val value: Int) : Number, Body, LogicOperand() {
    // Integers are already evaluated
    override fun simplify(subs: Substitutions): Simplification = Simplification(this, this)

    override fun satisfy(subs: Substitutions): Answers = sequenceOf(Result.success(emptyMap()))

    override fun toString(): String = value.toString()

    override operator fun plus(other: Number): Number = when (other) {
        is Float -> Float(value + other.value)
        is Integer -> Integer(value + other.value)
        else -> throw IllegalArgumentException("Cannot add $this and $other")
    }

    override operator fun minus(other: Number): Number = when (other) {
        is Float -> Float(value - other.value)
        is Integer -> Integer(value - other.value)
        else -> throw IllegalArgumentException("Cannot subtract $this and $other")
    }

    override operator fun div(other: Number): Number = when (other) {
        is Float -> Float(value / other.value)
        is Integer -> {
            if (value / other.value * other.value == value) {
                Integer(value / other.value)
            } else {
                Float(value / other.value.toFloat())
            }
        }

        else -> throw IllegalArgumentException("Cannot divide $this and $other")
    }

    override operator fun times(other: Number): Number = when (other) {
        is Float -> Float(value * other.value)
        is Integer -> Integer(value * other.value)
        else -> throw IllegalArgumentException("Cannot multiply $this and $other")
    }

    override fun applySubstitution(subs: Substitutions): Integer = this
}
