// Path: src/main/java/org/logic2j/core/api/library/LibraryContent.java
// public class LibraryContent {
// 
//   private final Map<String, PrimitiveInfo> directiveMap = new HashMap<>();
// 
//   private final Map<String, PrimitiveInfo> predicateMap = new HashMap<>();
// 
//   private final Map<String, PrimitiveInfo> functorMap = new HashMap<>();
// 
//   private final Map<String, PrimitiveInfo> primitiveMap = new HashMap<>();
// 
//   private List<Function<Struct<?>, Struct<?>>> foPredicateFactories = new ArrayList<>();
// 
//   public void putDirective(String theKey, PrimitiveInfo theDesc) {
//     if (this.directiveMap.containsKey(theKey)) {
//       throw new PrologNonSpecificException("A directive is already defined for key " + theKey + ", cannot override with " + theDesc);
//     }
//     this.directiveMap.put(theKey, theDesc);
//   }
// 
//   public void putPredicate(String theKey, PrimitiveInfo theDesc) {
//     if (this.predicateMap.containsKey(theKey)) {
//       throw new PrologNonSpecificException("A predicate is already defined for key " + theKey + ", cannot override with " + theDesc);
//     }
//     this.predicateMap.put(theKey, theDesc);
//   }
// 
//   public void putFunctor(String theKey, PrimitiveInfo theDesc) {
//     if (this.functorMap.containsKey(theKey)) {
//       throw new PrologNonSpecificException("A functor is already defined for key " + theKey + ", cannot override with " + theDesc);
//     }
//     this.functorMap.put(theKey, theDesc);
//   }
// 
//   public void putPrimitive(String theKey, PrimitiveInfo theDesc) {
//     if (this.primitiveMap.containsKey(theKey)) {
//       throw new PrologNonSpecificException("A primitive is already defined for key " + theKey + ", cannot override with " + theDesc);
//     }
//     switch (theDesc.getType()) {
//       case DIRECTIVE:
//         putDirective(theKey, theDesc);
//         break;
//       case PREDICATE:
//         putPredicate(theKey, theDesc);
//         break;
//       case FUNCTOR:
//         putFunctor(theKey, theDesc);
//         break;
//       default:
//         assert false : "Unplanned case in switch on PrimitiveType";
//     }
// 
//     this.primitiveMap.put(theKey, theDesc);
//   }
// 
//   /**
//    * Merge the content of theLoadedContent into this, by adding all directives, primitives, functors and predicates.
//    *
//    * @param theLoadedContent
//    */
//   public void addAll(LibraryContent theLoadedContent) {
//     this.directiveMap.putAll(theLoadedContent.directiveMap);
//     this.predicateMap.putAll(theLoadedContent.predicateMap);
//     this.functorMap.putAll(theLoadedContent.functorMap);
//     this.primitiveMap.putAll(theLoadedContent.primitiveMap);
//   }
// 
// 
//   public void addFOPredicateFactory(Function<Struct<?>, Struct<?>>... factory) {
//     Arrays.stream(factory).forEach(getFOPredicateFactories()::add);
//   }
// 
//   // --------------------------------------------------------------------------
//   // Accessors
//   // --------------------------------------------------------------------------
// 
//   /**
//    * @param thePredicateSignature
//    * @return The {@link PrimitiveInfo} for the specified primitive's signature, or null when not registered in this {@link LibraryContent}
//    */
//   public PrimitiveInfo getPrimitive(String thePredicateSignature) {
//     return this.primitiveMap.get(thePredicateSignature);
//   }
// 
//   public boolean hasPrimitive(String thePredicateSignature) {
//     return this.primitiveMap.containsKey(thePredicateSignature);
//   }
// 
//   public List<Function<Struct<?>, Struct<?>>> getFOPredicateFactories() {
//     return foPredicateFactories;
//   }
// 
//   public void setFOPredicateFactories(List<Function<Struct<?>, Struct<?>>> foPredicateFactories) {
//     this.foPredicateFactories = foPredicateFactories;
//   }
// }
// 
// Path: src/main/java/org/logic2j/core/api/library/PLibrary.java
// public interface PLibrary {
// 
//   String NO_DIRECT_INVOCATION_USE_REFLECTION = "no-direct-invocation-use-reflection";
// 
//   /**
//    * The dispatcher allow direct invocation of the primitives, without the need for reflection,
//    * for performance reasons.
//    *
//    * @param theMethodName
//    * @param theGoalStruct
//    * @param currentVars
//    * @return
//    */
//   Object dispatch(String theMethodName, Struct<?> theGoalStruct, UnifyContext currentVars);
// 
// }


import org.logic2j.core.api.library.LibraryContent;
import org.logic2j.core.api.library.PLibrary;
/*
 * logic2j - "Bring Logic to your Java" - Copyright (c) 2017 Laurent.Tettoni@gmail.com
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Foobar is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser Public License for more details.
 *
 * You should have received a copy of the GNU Lesser Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.logic2j.core.api;


/**
 * An API to manage {@link org.logic2j.core.api.library.PLibrary}es implementing Prolog primitives in Java.
 */
public interface LibraryManager {

  /**
   * Load a {@link org.logic2j.core.api.library.PLibrary}
   *
   * @param theLibrary
   * @return The content of the library
   */
  LibraryContent loadLibrary(PLibrary theLibrary);

  /**
   * @return The whole {@link PLibrary}'s content.
   */
// Path: src/main/java/org/logic2j/core/api/library/LibraryContent.java
// public class LibraryContent {
// 
//   private final Map<String, PrimitiveInfo> directiveMap = new HashMap<>();
// 
//   private final Map<String, PrimitiveInfo> predicateMap = new HashMap<>();
// 
//   private final Map<String, PrimitiveInfo> functorMap = new HashMap<>();
// 
//   private final Map<String, PrimitiveInfo> primitiveMap = new HashMap<>();
// 
//   private List<Function<Struct<?>, Struct<?>>> foPredicateFactories = new ArrayList<>();
// 
//   public void putDirective(String theKey, PrimitiveInfo theDesc) {
//     if (this.directiveMap.containsKey(theKey)) {
//       throw new PrologNonSpecificException("A directive is already defined for key " + theKey + ", cannot override with " + theDesc);
//     }
//     this.directiveMap.put(theKey, theDesc);
//   }
// 
//   public void putPredicate(String theKey, PrimitiveInfo theDesc) {
//     if (this.predicateMap.containsKey(theKey)) {
//       throw new PrologNonSpecificException("A predicate is already defined for key " + theKey + ", cannot override with " + theDesc);
//     }
//     this.predicateMap.put(theKey, theDesc);
//   }
// 
//   public void putFunctor(String theKey, PrimitiveInfo theDesc) {
//     if (this.functorMap.containsKey(theKey)) {
//       throw new PrologNonSpecificException("A functor is already defined for key " + theKey + ", cannot override with " + theDesc);
//     }
//     this.functorMap.put(theKey, theDesc);
//   }
// 
//   public void putPrimitive(String theKey, PrimitiveInfo theDesc) {
//     if (this.primitiveMap.containsKey(theKey)) {
//       throw new PrologNonSpecificException("A primitive is already defined for key " + theKey + ", cannot override with " + theDesc);
//     }
//     switch (theDesc.getType()) {
//       case DIRECTIVE:
//         putDirective(theKey, theDesc);
//         break;
//       case PREDICATE:
//         putPredicate(theKey, theDesc);
//         break;
//       case FUNCTOR:
//         putFunctor(theKey, theDesc);
//         break;
//       default:
//         assert false : "Unplanned case in switch on PrimitiveType";
//     }
// 
//     this.primitiveMap.put(theKey, theDesc);
//   }
// 
//   /**
//    * Merge the content of theLoadedContent into this, by adding all directives, primitives, functors and predicates.
//    *
//    * @param theLoadedContent
//    */
//   public void addAll(LibraryContent theLoadedContent) {
//     this.directiveMap.putAll(theLoadedContent.directiveMap);
//     this.predicateMap.putAll(theLoadedContent.predicateMap);
//     this.functorMap.putAll(theLoadedContent.functorMap);
//     this.primitiveMap.putAll(theLoadedContent.primitiveMap);
//   }
// 
// 
//   public void addFOPredicateFactory(Function<Struct<?>, Struct<?>>... factory) {
//     Arrays.stream(factory).forEach(getFOPredicateFactories()::add);
//   }
// 
//   // --------------------------------------------------------------------------
//   // Accessors
//   // --------------------------------------------------------------------------
// 
//   /**
//    * @param thePredicateSignature
//    * @return The {@link PrimitiveInfo} for the specified primitive's signature, or null when not registered in this {@link LibraryContent}
//    */
//   public PrimitiveInfo getPrimitive(String thePredicateSignature) {
//     return this.primitiveMap.get(thePredicateSignature);
//   }
// 
//   public boolean hasPrimitive(String thePredicateSignature) {
//     return this.primitiveMap.containsKey(thePredicateSignature);
//   }
// 
//   public List<Function<Struct<?>, Struct<?>>> getFOPredicateFactories() {
//     return foPredicateFactories;
//   }
// 
//   public void setFOPredicateFactories(List<Function<Struct<?>, Struct<?>>> foPredicateFactories) {
//     this.foPredicateFactories = foPredicateFactories;
//   }
// }
// 
// Path: src/main/java/org/logic2j/core/api/library/PLibrary.java
// public interface PLibrary {
// 
//   String NO_DIRECT_INVOCATION_USE_REFLECTION = "no-direct-invocation-use-reflection";
// 
//   /**
//    * The dispatcher allow direct invocation of the primitives, without the need for reflection,
//    * for performance reasons.
//    *
//    * @param theMethodName
//    * @param theGoalStruct
//    * @param currentVars
//    * @return
//    */
//   Object dispatch(String theMethodName, Struct<?> theGoalStruct, UnifyContext currentVars);
// 
// }


// Path: src/main/java/org/logic2j/core/api/LibraryManager.java
import org.logic2j.core.api.library.LibraryContent;
import org.logic2j.core.api.library.PLibrary;

/*
 * logic2j - "Bring Logic to your Java" - Copyright (c) 2017 Laurent.Tettoni@gmail.com
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Foobar is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser Public License for more details.
 *
 * You should have received a copy of the GNU Lesser Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.logic2j.core.api;


/**
 * An API to manage {@link org.logic2j.core.api.library.PLibrary}es implementing Prolog primitives in Java.
 */
public interface LibraryManager {

  /**
   * Load a {@link org.logic2j.core.api.library.PLibrary}
   *
   * @param theLibrary
   * @return The content of the library
   */
  LibraryContent loadLibrary(PLibrary theLibrary);

  /**
   * @return The whole {@link PLibrary}'s content.
   */
  LibraryContent wholeContent();