package prolog.logic import prolog.Substitutions import prolog.ast.terms.CompoundTerm import prolog.ast.terms.Term import prolog.ast.terms.Variable /** * True if [Term] is bound (i.e., not a variable) and is not compound. * Thus, atomic acts as if defined by: * * atomic(Term) :- * nonvar(Term), * \+ compound(Term). */ fun atomic(term: Term, subs: Substitutions = emptyMap()): Boolean = nonvariable(term, subs) && !compound(term, subs) /** * True if [Term] is bound to a compound term. * See also functor/3 =../2, compound_name_arity/3 and compound_name_arguments/3. */ fun compound(term: Term, subs: Substitutions = emptyMap()): Boolean { val isCompound = term is CompoundTerm val isVariableCompound = term is Variable && term in subs && compound(subs[term]!!, subs) return isCompound || isVariableCompound } /** * True if [Term] currently is not a free variable. */ fun nonvariable(term: Term, subs: Substitutions = emptyMap()): Boolean = !variable(term, subs) /** * True if [Term] currently is a free variable. */ fun variable(term: Term, subs: Substitutions = emptyMap()): Boolean { if (term is Variable) { return term !in subs || subs[term] === term || variable(subs[term]!!, subs) } return false }