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