package prolog.logic 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): Boolean = nonvariable(term) && !compound(term) /** * 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): Boolean { val isCompound = term is CompoundTerm val isVariableCompound = term is Variable && term.alias().isPresent && compound(term.alias().get()) return isCompound || isVariableCompound } /** * True if [Term] currently is not a free variable. */ fun nonvariable(term: Term): Boolean = !variable(term) /** * True if [Term] currently is a free variable. */ fun variable(term: Term): Boolean { if (term is Variable) { return term.alias().isEmpty || term.alias().get() === term || variable(term.alias().get()) } return false }