<commit_before>package planstack.anml.model

import planstack.anml.model.abs.{AbstractAction, AbstractTemporalConstraint, StatementsFactory}
import planstack.anml.model.concrete._
import planstack.anml.parser.{ANMLFactory, ParseResult}
import planstack.anml.{ANMLException, parser}

import scala.collection.JavaConversions._

/** Description of an ANML problem.
  *
  * An ANML problem comes with three time points: start (global start of the world the problem takes place in),
  * end (global end of the world) and earliestExecution which represent the earliest time at which an action can be executed.
  * Temporal intervals (such as actions, statements, ...) are placed relatively to the start and end time points using
  * [[planstack.anml.model.concrete.TemporalConstraint]].
  * The earliestExecution time point will not have any explicit constraints linked to it (we consider this choice is
  * plannner-dependent and is not explicitly defined in ANML).
  *
  * Components include:
  *
  *  - an [[planstack.anml.model.InstanceManager]] that keeps track of all types and instances declared
  * in the problem.
  *
  *  - a [[planstack.anml.model.FunctionManager]] that records of all functions declared in the ANML problem.
  *
  *  - a [[planstack.anml.model.Context]] that map local variables and references that appear in the problem
  *  scope to global ones.
  *
  *
  * Further more an ANML problem consists of a list of [[planstack.anml.model.concrete.Chronicle]]
  * representing everything that must be added to plan solving this problem.
  * A first one is added in the constructor containing predefined instances of the problem (such as true and false).
  * Every time an `addAnml(...)` method it called, the problem's components are updated accordingly and a new
  * [[planstack.anml.model.concrete.Chronicle]] is added to represent the changes in the problems.
  *
  * @param usesActionConditions If set to true, the ANML problem will use ActionCondition instead of Action for representing subtasks.
  */
class AnmlProblem(val usesActionConditions : Boolean) extends TemporalInterval {

  /**
   * A time-point representing the earliest possible execution of an action.
   * Note that no explicit constraint including this timepoint is specified in the the ANML problem, it
   * is provided here mainly for consistency in the planner implementation. It is the responsability of the
   * planner to enforce the ordering between this time-point and the actions in the plan.
   */
  val earliestExecution : TPRef = new TPRef()

  /**
   * An InstanceManager that keeps track of all types and instances of the problem.
   */
  val instances = new InstanceManager

  /**
   * A [[planstack.anml.model.FunctionManager]] that keeps track of all functions (ie. definition of state variables)
   * in the problem.
   */
  val functions = new FunctionManager

  /** Context that all variables and and action that appear in the problem scope.
    * Those typically contain instances of the problem and predefined ANML literals (such as true, false, ...)
    */
  val context = new Context(None)
  context.setInterval(this)

  /** All abstract actions appearing in the problem */
  val abstractActions = new java.util.LinkedList[AbstractAction]()

  /**
   * All [[planstack.anml.model.concrete.Chronicle]] that need to be applied to a state for it to represent this problem.
   * There is one chronicle encoding the default definitions of an ANML problem (such as the instances true and false of type
   * boolean). One chronicle is added by update of the problem (as a result of the invocation of `addAnml(...)`.
   */
  val chronicles = new java.util.LinkedList[Chronicle]()

  // create an initial chronicle containing the predefined instances (true and false)
  {
    val initialChronicle = new BaseChronicle(this)

    // add predefined instance to context and to StateModifier
    for((name, tipe) <- instances.instances) {
      initialChronicle.instances += name
      context.addVar(new LVarRef(name), tipe, instances.referenceOf(name))
    }

    chronicles += initialChronicle
  }

  /**
   * Retrieves the abstract action with the given name.
   * @param name Name of the action to lookup.
   * @return The corresponding AbstractAction.
   */
  def getAction(name:String) = abstractActions.find(_.name == name) match {
    case Some(act) => act
    case None => throw new ANMLException("No action named "+name)
  }

  /** Returns true if this problem definition contains an action with the given name */
  def containsAction(name:String) : Boolean = abstractActions.find(_.name == name) match {
    case Some(act) => true
    case None => false
  }

  /**
   * Extends this problem with the ANML found in the file.
   * If any updates need to be made to a search state as a consequence,
   * those are encoded as a Chronicle and added to `chronicles`
   * @param filename File in which the anml text can be found.
   */
  def extendWithAnmlFile(filename: String) : Unit = {
    addAnml(ANMLFactory.parseAnmlFromFile(filename))
  }<commit_msg>Load domain file when a problem file is given.<commit_after>package planstack.anml.model

import java.io.File

import planstack.anml.model.abs.{AbstractAction, AbstractTemporalConstraint, StatementsFactory}
import planstack.anml.model.concrete._
import planstack.anml.parser.{ANMLFactory, ParseResult}
import planstack.anml.{ANMLException, parser}


import scala.collection.JavaConverters._
import scala.collection.JavaConversions._

/** Description of an ANML problem.
  *
  * An ANML problem comes with three time points: start (global start of the world the problem takes place in),
  * end (global end of the world) and earliestExecution which represent the earliest time at which an action can be executed.
  * Temporal intervals (such as actions, statements, ...) are placed relatively to the start and end time points using
  * [[planstack.anml.model.concrete.TemporalConstraint]].
  * The earliestExecution time point will not have any explicit constraints linked to it (we consider this choice is
  * plannner-dependent and is not explicitly defined in ANML).
  *
  * Components include:
  *
  *  - an [[planstack.anml.model.InstanceManager]] that keeps track of all types and instances declared
  * in the problem.
  *
  *  - a [[planstack.anml.model.FunctionManager]] that records of all functions declared in the ANML problem.
  *
  *  - a [[planstack.anml.model.Context]] that map local variables and references that appear in the problem
  *  scope to global ones.
  *
  *
  * Further more an ANML problem consists of a list of [[planstack.anml.model.concrete.Chronicle]]
  * representing everything that must be added to plan solving this problem.
  * A first one is added in the constructor containing predefined instances of the problem (such as true and false).
  * Every time an `addAnml(...)` method it called, the problem's components are updated accordingly and a new
  * [[planstack.anml.model.concrete.Chronicle]] is added to represent the changes in the problems.
  *
  * @param usesActionConditions If set to true, the ANML problem will use ActionCondition instead of Action for representing subtasks.
  */
class AnmlProblem(val usesActionConditions : Boolean) extends TemporalInterval {

  /**
   * A time-point representing the earliest possible execution of an action.
   * Note that no explicit constraint including this timepoint is specified in the the ANML problem, it
   * is provided here mainly for consistency in the planner implementation. It is the responsability of the
   * planner to enforce the ordering between this time-point and the actions in the plan.
   */
  val earliestExecution : TPRef = new TPRef()

  /**
   * An InstanceManager that keeps track of all types and instances of the problem.
   */
  val instances = new InstanceManager

  /**
   * A [[planstack.anml.model.FunctionManager]] that keeps track of all functions (ie. definition of state variables)
   * in the problem.
   */
  val functions = new FunctionManager

  /** Context that all variables and and action that appear in the problem scope.
    * Those typically contain instances of the problem and predefined ANML literals (such as true, false, ...)
    */
  val context = new Context(None)
  context.setInterval(this)

  /** All abstract actions appearing in the problem */
  val abstractActions = new java.util.LinkedList[AbstractAction]()

  /**
   * All [[planstack.anml.model.concrete.Chronicle]] that need to be applied to a state for it to represent this problem.
   * There is one chronicle encoding the default definitions of an ANML problem (such as the instances true and false of type
   * boolean). One chronicle is added by update of the problem (as a result of the invocation of `addAnml(...)`.
   */
  val chronicles = new java.util.LinkedList[Chronicle]()

  // create an initial chronicle containing the predefined instances (true and false)
  {
    val initialChronicle = new BaseChronicle(this)

    // add predefined instance to context and to StateModifier
    for((name, tipe) <- instances.instances) {
      initialChronicle.instances += name
      context.addVar(new LVarRef(name), tipe, instances.referenceOf(name))
    }

    chronicles += initialChronicle
  }

  /**
   * Retrieves the abstract action with the given name.
   * @param name Name of the action to lookup.
   * @return The corresponding AbstractAction.
   */
  def getAction(name:String) = abstractActions.find(_.name == name) match {
    case Some(act) => act
    case None => throw new ANMLException("No action named "+name)
  }

  /** Returns true if this problem definition contains an action with the given name */
  def containsAction(name:String) : Boolean = abstractActions.find(_.name == name) match {
    case Some(act) => true
    case None => false
  }

  /**
   * Extends this problem with the ANML found in the file.
   * It the file name is formatted as xxxxxx.yyy.pb.anml, it will load the file
   * xxxxxx.dom.anml as well.
   * If any updates need to be made to a search state as a consequence,
   * those are encoded as a Chronicle and added to `chronicles`
   * @param filename File in which the anml text can be found.
   */
  def extendWithAnmlFile(filename: String) : Unit = {
    if(filename.endsWith(".pb.anml")) {
      val f = new File(filename)
      f.getName.split("\\.").toList match {
        case base :: num :: "pb" :: "anml" :: Nil =>
          addAnml(ANMLFactory.parseAnmlFromFile(new File(f.getParentFile, base+".dom.anml").getAbsolutePath))
        case _ =>
          throw new ANMLException("Error: file name does not follow the convention: "+filename+"."+
           "It should be in the form domainName.xxx.pb.anml and have an associated domainName.dom.anml file.")
      }
    }
    addAnml(ANMLFactory.parseAnmlFromFile(filename))
  }
{'fraction_non_alphanumeric': 0.08070013818516812, 'fraction_numerical': 0.0, 'mean_word_length': 3.6393162393162393, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3867084', 'n_tokens_mistral': 2949, 'n_tokens_neox': 2899, 'n_words': 1241}