All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.nicopolyptic.state.Expression.scala Maven / Gradle / Ivy

The newest version!
/**
  *     _   ___                        __            __  _
  *    / | / (_)________  ____  ____  / /_  ______  / /_(_)____
  *   /  |/ / / ___/ __ \/ __ \/ __ \/ / / / / __ \/ __/ / ___/
  *  / /|  / / /__/ /_/ / /_/ / /_/ / / /_/ / /_/ / /_/ / /__
  * /_/ |_/_/\___/\____/ .___/\____/_/\__, / .___/\__/_/\___/
  *                   /_/            /____/_/
  *
  **/

package com.nicopolyptic.state

trait Exp[X] extends Serializable {
  def | (e:Exp[X]) = SumExp(this, e)
  def >> (e:Exp[X]) = CatExp(this, e)
  def ** = StarExp(this)
  override def toString() = Exp.print(this)
  def matches[S, Y](s : Seq[S])(implicit
                             i : Interpretation[Y,S],
                             f : Exp[X] => Exp[Y]
                            ) = Automaton.create(f(this)).accepts(s)
}

abstract class Id(val id : Int)

case class Prop[X](x:X) extends Id(Exp.nextId) with Exp[X] {
  override def hashCode(): Int = id.hashCode()
  override def equals(obj: scala.Any): Boolean = id.equals(obj.asInstanceOf[Prop[X]].id)
}

case class StarExp[X](e : Exp[X]) extends Exp[X]

case class CatExp[X](left: Exp[X], right:Exp[X]) extends Exp[X]

case class SumExp[X](left: Exp[X], right:Exp[X]) extends Exp[X]

private object Exp {

  def print(e : Exp[_]): String =
    e match {
      case Prop(x) => x.toString()
      case StarExp(e) => s"( ${print(e)})*"
      case CatExp(e, e2) => s"(${print(e)}; ${print(e2)})"
      case SumExp(e, e2) => s"(${print(e)} | ${print(e2)})"
    }

  var id = 0
  def nextId = { id += 1; id }

  def empty(e: Exp[_]) : Boolean =
    e match {
      case _ : Prop[_] => false
      case StarExp(e) => true
      case CatExp(e,e2) => empty(e) && empty(e2)
      case SumExp(e, e2) => empty(e) || empty(e2)
    }

  def first[X](e:Exp[X]) : Set[Int] =
    e match {
      case a : Prop[X] => Set(a.id)
      case StarExp(e) => first(e)
      case CatExp(e,e2) => if (empty(e)) first(e2) ++ first(e) else first(e)
      case SumExp(e, e2) => first(e) ++ first(e2)
    }

  def last[X](e:Exp[X]) : Set[Int] =
    e match {
      case a:Prop[X] => Set(a.id)
      case StarExp(e) => last(e)
      case CatExp(e,e2) => if (empty(e2)) last(e) ++ last(e2) else last(e2)
      case SumExp(e, e2) => last(e) ++ last(e2)
    }

  def next[X](e: Exp[X]) : Set[(Int, Int)] =
    e match {
      case CatExp(e1,e2) => next(e1) ++ next(e2) ++ (for (l <- last(e1); f <- first(e2)) yield l -> f)
      case StarExp(e) => next(e) ++ (for (l <- last(e); f <- first(e)) yield l -> f)
      case SumExp(e1,e2) => next(e1) ++ next(e2)
      case _ => Set.empty
    }

  def leaves[X](e :Exp[X]): Set[Prop[X]] =
    e match {
      case CatExp(e1,e2) => leaves(e1) ++ leaves(e2)
      case StarExp(e) => leaves(e)
      case SumExp(e1,e2) => leaves(e1) ++ leaves(e2)
      case a:Prop[X] => Set(a)
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy