package prolog.ast.terms

import prolog.Substitutions
import prolog.ast.arithmetic.Integer

data class Functor(val name: Atom, val arity: Integer) : Term {
    constructor(name: String, arity: Int) : this(Atom(name), Integer(arity))

    companion object {
        fun of(functor: String): Functor {
            // Split the functor string into name and arity, by splitting the last "/"
            val lastSlash = functor.lastIndexOf('/')
            val name = Atom(functor.substring(0, lastSlash))
            val arity = Integer(functor.substring(lastSlash + 1).toIntOrNull() ?: 0)
            return Functor(name, arity)
        }
    }

    override fun toString(): String = "${name.name}/$arity"
    override fun applySubstitution(subs: Substitutions) : Functor = this

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (other == null) return false
        if (other !is Functor && other !is String) return false
        if (other is Functor) {
            return this.name.toString() == other.name.toString() && this.arity == other.arity
        }
        return this.toString() == other
    }

    override fun hashCode(): Int {
        var result = name.hashCode()
        result = 31 * result + arity.hashCode()
        return result
    }
}
