<commit_before>package fr.laas.fape.planning.events

import fr.laas.fape.anml.model
import fr.laas.fape.anml.model.concrete._
import fr.laas.fape.anml.model.concrete.statements.{Assignment, Persistence, Transition}
import fr.laas.fape.anml.model.{AnmlProblem, ParameterizedStateVariable, SymFunction}
import fr.laas.fape.constraints.meta.CSP
import fr.laas.fape.constraints.meta.events.{Event, InternalCSPEventHandler}
import fr.laas.fape.constraints.meta.stn.constraint.{Contingent, MinDelay}
import fr.laas.fape.constraints.meta.stn.variables.Timepoint
import fr.laas.fape.constraints.meta.util.Assertion._
import fr.laas.fape.planning.causality.CausalHandler
import fr.laas.fape.planning.causality.support.SupportByAction
import fr.laas.fape.planning.structures.{Change, Holds}
import fr.laas.fape.planning.types.{AnmlVarType, TypeHandler}
import fr.laas.fape.planning.variables.{FVar, InstanceVar, SVar, Var}

import scala.collection.JavaConverters._
import scala.collection.mutable

class PlanningHandler(_csp: CSP, base: Either[AnmlProblem, PlanningHandler]) extends InternalCSPEventHandler {

  implicit val csp = _csp
  def log = csp.log

  assert1(!csp.conf.enforceTpAfterStart, "Planner needs to be able some timepoints before the CSP's temporal origin.")

  val pb: AnmlProblem = base match {
    case Left(pb) => pb
    case Right(prev) => prev.pb
  }

  val variables: mutable.Map[VarRef, Var] = base match {
    case Right(prev) => prev.variables.clone()
    case Left(_) => mutable.Map()
  }

  val stateVariables: mutable.Map[ParameterizedStateVariable, SVar] = base match {
    case Right(prev) => prev.stateVariables.clone()
    case Left(_) => mutable.Map()
  }

  val functionVars: mutable.Map[SymFunction, FVar] = base match {
    case Left(_) => mutable.Map()
    case Right(prev) => prev.functionVars.clone()
  }

  val types: TypeHandler = base match {
    case Left(_) => new TypeHandler(pb)
    case Right(prev) => prev.types
  }

  val actions: mutable.ArrayBuffer[Action] = base match {
    case Right(prev) => prev.actions.clone()
    case Left(_) => mutable.ArrayBuffer()
  }

  // last since causal handler typically need to access types and variables
  val subhandlers: mutable.ArrayBuffer[PlanningEventHandler] = base match {
    case Left(_) => mutable.ArrayBuffer(new CausalHandler(this))
    case Right(prev) => prev.subhandlers.map(_.clone(this))
  }

  def variable(v: VarRef): Var = v match {
    case v: InstanceRef =>
      variables.getOrElseUpdate(v, new InstanceVar(v, types.get(v.typ)))
    case _ =>
      variables.getOrElseUpdate(v, new Var(v, types.get(v.typ)))
  }

  def func(f: model.Function): FVar = f match {
    case f: SymFunction => functionVars.getOrElseUpdate(f, new FVar(f, types.functionType))
    case _ => throw new NotImplementedError()
  }

  def sv(psv: ParameterizedStateVariable): SVar =
    stateVariables.getOrElseUpdate(psv, new SVar(func(psv.func), psv.args.toList.map(variable(_)), psv))

  def getHandler[T](clazz: Class[T]) : T = subhandlers.filter(_.getClass == clazz).toList match {
    case Nil => throw new IllegalArgumentException("No handler of such type")
    case h :: Nil => h.asInstanceOf[T]
    case list => throw new IllegalArgumentException("Multiple handlers of such type")
  }

  def tp(tpRef: TPRef): Timepoint =
    if(tpRef == pb.start)
      csp.temporalOrigin
    else if(tpRef == pb.end)
      csp.temporalHorizon
    else
      csp.varStore.getTimepoint(tpRef)

  def insertChronicle(chronicle: Chronicle) {
    for(c <- chronicle.bindingConstraints.asScala)  c match {
      case c: VarInequalityConstraint =>
        csp.post(variable(c.leftVar) =!= variable(c.rightVar))
      case c: VarEqualityConstraint =>
        csp.post(variable(c.leftVar) === variable(c.rightVar))
    }
    for(c <- chronicle.temporalConstraints.asScala) c match {
      case c: MinDelayConstraint =><commit_msg>[planning] Add support for constraints over constant functions.<commit_after>package fr.laas.fape.planning.events

import fr.laas.fape.anml.model
import fr.laas.fape.anml.model.concrete._
import fr.laas.fape.anml.model.concrete.statements.{Assignment, Persistence, Transition}
import fr.laas.fape.anml.model.{AnmlProblem, ParameterizedStateVariable, SymFunction}
import fr.laas.fape.constraints.meta.CSP
import fr.laas.fape.constraints.meta.constraints.ExtensionConstraint
import fr.laas.fape.constraints.meta.domains.ExtensionDomain
import fr.laas.fape.constraints.meta.events.{Event, InternalCSPEventHandler}
import fr.laas.fape.constraints.meta.stn.constraint.{Contingent, MinDelay}
import fr.laas.fape.constraints.meta.stn.variables.Timepoint
import fr.laas.fape.constraints.meta.util.Assertion._
import fr.laas.fape.planning.causality.CausalHandler
import fr.laas.fape.planning.causality.support.SupportByAction
import fr.laas.fape.planning.structures.{Change, Holds}
import fr.laas.fape.planning.types.{AnmlVarType, TypeHandler}
import fr.laas.fape.planning.variables.{FVar, InstanceVar, SVar, Var}

import scala.collection.JavaConverters._
import scala.collection.mutable

class PlanningHandler(_csp: CSP, base: Either[AnmlProblem, PlanningHandler]) extends InternalCSPEventHandler {

  implicit val csp = _csp
  def log = csp.log

  assert1(!csp.conf.enforceTpAfterStart, "Planner needs to be able some timepoints before the CSP's temporal origin.")

  val pb: AnmlProblem = base match {
    case Left(anmlProblem) => anmlProblem
    case Right(prev) => prev.pb
  }

  val variables: mutable.Map[VarRef, Var] = base match {
    case Right(prev) => prev.variables.clone()
    case Left(_) => mutable.Map()
  }

  val stateVariables: mutable.Map[ParameterizedStateVariable, SVar] = base match {
    case Right(prev) => prev.stateVariables.clone()
    case Left(_) => mutable.Map()
  }

  val functionVars: mutable.Map[SymFunction, FVar] = base match {
    case Left(_) => mutable.Map()
    case Right(prev) => prev.functionVars.clone()
  }

  val types: TypeHandler = base match {
    case Left(_) => new TypeHandler(pb)
    case Right(prev) => prev.types
  }

  val actions: mutable.ArrayBuffer[Action] = base match {
    case Right(prev) => prev.actions.clone()
    case Left(_) => mutable.ArrayBuffer()
  }

  val extensionDomains: mutable.Map[model.Function, ExtensionDomain] = base match {
    case Right(prev) => prev.extensionDomains.clone()
    case Left(_) => mutable.Map()
  }

  // last since causal handler typically need to access types and variables
  val subhandlers: mutable.ArrayBuffer[PlanningEventHandler] = base match {
    case Left(_) => mutable.ArrayBuffer(new CausalHandler(this))
    case Right(prev) => prev.subhandlers.map(_.clone(this))
  }

  def variable(v: VarRef): Var = v match {
    case v: InstanceRef =>
      variables.getOrElseUpdate(v, new InstanceVar(v, types.get(v.typ)))
    case _ =>
      variables.getOrElseUpdate(v, new Var(v, types.get(v.typ)))
  }

  def func(f: model.Function): FVar = f match {
    case f: SymFunction => functionVars.getOrElseUpdate(f, new FVar(f, types.functionType))
    case _ => throw new NotImplementedError()
  }

  def sv(psv: ParameterizedStateVariable): SVar =
    stateVariables.getOrElseUpdate(psv, new SVar(func(psv.func), psv.args.toList.map(variable(_)), psv))

  def getHandler[T](clazz: Class[T]) : T = subhandlers.filter(_.getClass == clazz).toList match {
    case Nil => throw new IllegalArgumentException("No handler of such type")
    case h :: Nil => h.asInstanceOf[T]
    case list => throw new IllegalArgumentException("Multiple handlers of such type")
  }

  def tp(tpRef: TPRef): Timepoint =
    if(tpRef == pb.start)
      csp.temporalOrigin
    else if(tpRef == pb.end)
      csp.temporalHorizon
    else
      csp.varStore.getTimepoint(tpRef)

  def insertChronicle(chronicle: Chronicle) {
    for(c <- chronicle.bindingConstraints.asScala)  c match {
      case c: VarInequalityConstraint =>
        csp.post(variable(c.leftVar) =!= variable(c.rightVar))
      case c: VarEqualityConstraint =>
        csp.post(variable(c.leftVar) === variable(c.rightVar))
      case c: AssignmentConstraint =>
        val func = c.sv.func
        assert1((c.sv.args.toList :+ c.variable).forall(variable(_).domain.isSingleton))
        val values = (c.sv.args.toList :+ c.variable).map(variable(_).domain.head)
        extensionDomains.getOrElseUpdate(func, new ExtensionDomain(values.size)).addTuple(values)
      case c: EqualityConstraint =>
        val variables = (c.sv.args.toList :+ c.variable).map(variable(_))
        csp.post(new ExtensionConstraint(variables, extensionDomains.getOrElseUpdate(c.sv.func, new ExtensionDomain(variables.size))))
      case x =>
        throw new NotImplementedError(s"Support for constraint $x is not implemented.")
    }
    for(c <- chronicle.temporalConstraints.asScala) c match {
      case c: MinDelayConstraint =>
{'fraction_non_alphanumeric': 0.12241203756081005, 'fraction_numerical': 0.0003394049100576988, 'mean_word_length': 4.148514851485149, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 56, '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': '6893420', 'n_tokens_mistral': 2947, 'n_tokens_neox': 2886, 'n_words': 613}