package prolog.ast import io.Logger import prolog.Program import prolog.Answers import prolog.Substitutions import prolog.ast.logic.Clause import prolog.ast.logic.Predicate import prolog.ast.logic.Resolvent import prolog.ast.terms.Functor import prolog.ast.terms.Goal /** * Prolog Program or Database */ class Database(val sourceFile: String): Resolvent { var predicates: Map = emptyMap() fun initialize() { Logger.info("Initializing database from $sourceFile") if (predicates.contains("/_")) { Logger.debug("Loading clauses from /_ predicate") predicates["/_"]?.clauses?.forEach { Logger.debug("Loading clause $it") val goal = it.body as Goal goal.satisfy(emptyMap()).toList() } } } override fun solve(goal: Goal, subs: Substitutions): Answers { val functor = goal.functor // If the predicate does not exist, return false val predicate = predicates[functor] ?: return emptySequence() // If the predicate exists, evaluate the goal against it return predicate.solve(goal, subs) } /** * Loads a list of clauses into the program. */ fun load(clauses: List, index: Int? = null) { for (clause in clauses) { val functor = clause.functor val predicate = predicates[functor] if (predicate != null) { // If the predicate already exists, add the clause to it predicate.add(clause, index) } else { // If the predicate does not exist, create a new one predicates += Pair(functor, Predicate(listOf(clause))) } Logger.debug("Loaded clause $clause into predicate $functor") } } fun load(predicate: Predicate) { val functor = predicate.functor val existingPredicate = predicates[functor] if (existingPredicate != null) { // If the predicate already exists, add the clauses to it existingPredicate.addAll(predicate.clauses) } else { // If the predicate does not exist, create a new one predicates += Pair(functor, predicate) } } fun clear() { Logger.debug("Clearing ${this::class.java.simpleName}") predicates = emptyMap() } }