axle.lx.Angluin.scala Maven / Gradle / Ivy
The newest version!
package axle.lx
import axle.graph.JungDirectedGraph
import axle.graph.Vertex
import spire.algebra.Eq
import spire.implicits.StringOrder
import spire.implicits.eqOps
object Angluin {
case class Symbol(s: String) {
override def toString: String = s
}
object Symbol {
implicit val symbolEq = new Eq[Symbol] {
def eqv(x: Symbol, y: Symbol): Boolean = x equals y
}
}
class AngluinAcceptor(vps: Seq[String], I: Set[String], F: Set[String]) {
val graph = JungDirectedGraph[String, Symbol](vps, vs => Nil)
def Q: Set[Vertex[String]] = graph.vertices
// def addState(isInitial: Boolean, isFinal: Boolean): Acceptor = {
// val (newG, v) = g + "" // TODO
// val newI = isInitial ? (I + v.payload) | I
// val newF = isFinal ? (F + v.payload) | F
// Acceptor(newG, newI, newF)
// }
def δSymbol(state: Vertex[String], symbol: Symbol): Set[Vertex[String]] =
graph.allEdges.collect({ case e if graph.source(e) === state && e.payload === symbol => graph.dest(e) })
def δ(state: Vertex[String], exp: List[Symbol]): Set[String] = exp match {
case head :: tail => δSymbol(state, head).map(δ(_, tail)).reduce(_ ++ _)
case Nil => Set(state.payload)
}
// TODO: not sure if this should count edges or nodes:
// def isForwardDeterministic(): Boolean = (I.size <= 1) && Q.∀(successors(_).size <= 1)
// def isBackwardDeterministic(): Boolean = (F.size <= 1) && Q.∀(predecessors(_).size <= 1)
// def isZeroReversible(): Boolean = isForwardDeterministic() && isBackwardDeterministic()
def isIsomorphicTo(other: AngluinAcceptor): Boolean = ???
def isSubacceptorOf(other: AngluinAcceptor): Boolean = ???
def induce(P: Set[Vertex[String]]): AngluinAcceptor = ???
}
// type Expression = List[Symbol]
val ♯ = List[Symbol]()
// val g = graph[String, Symbol]()
case class CanonicalAcceptorFactory() {
def makeCanonicalAcceptor(ℒ: Language): AngluinAcceptor = ???
}
class ExpressionComparator extends Comparable[List[Symbol]] {
def compareTo(other: List[Symbol]) = (this.toString()).compareTo(other.toString)
// def compare(o1: Expression, o2: Expression): Int = (o1.toString()).compareTo(o2.toString())
}
trait Grammar {
def ℒ: Language
}
case class HardCodedGrammar(_ℒ: Language) extends Grammar {
// Note: This was orginally a getter called simply ℒ()
// figure out how to write the extractor (or whatever)
// to grab this
def ℒ = _ℒ
}
case class Language(sequences: Iterable[Iterable[Symbol]] = Nil) {
def prefixes: Language = ???
def goodFinals(w: List[Symbol]): Language = ???
override def toString: String = "{" + sequences.mkString(", ") + "}"
}
object Language {
implicit val languageEq = new Eq[Language] {
def eqv(x: Language, y: Language): Boolean = x.sequences.equals(y.sequences)
}
}
trait Learner[S] {
def initialState: S
def processExpression(state: S, expression: Iterable[Symbol]): (S, Option[Grammar])
val noGuess = None.asInstanceOf[Option[Grammar]]
def guesses(T: Text): Iterator[Grammar] =
T.expressions.iterator
.scanLeft((initialState, noGuess))((sg, e) => processExpression(sg._1, e))
.flatMap(_._2)
}
/**
* The SilentLearner never makes a guess
*/
case class SilentLearner(T: Text) extends Learner[Nothing] {
def initialState() = null.asInstanceOf[Nothing]
def processExpression(state: Nothing, expression: Iterable[Symbol]) = (initialState, None)
}
/**
* The HardCodedLearner always guesses the same thing
*/
case class HardCodedLearner(G: Grammar) extends Learner[Nothing] {
def initialState: Nothing = null.asInstanceOf[Nothing]
def processExpression(state: Nothing, expression: Iterable[Symbol]): (Nothing, Option[Grammar]) =
(initialState, Some(G))
}
/**
* The MemorizingLearner accrues expressions
*/
case class MemorizingLearner() extends Learner[Language] {
def initialState: Language = Language(Nil)
def processExpression(state: Language, expression: Iterable[Symbol]): (Language, Option[Grammar]) =
expression match {
case ♯ => (state, Some(HardCodedGrammar(state)))
case _ => {
val newState = Language(state.sequences ++ List(expression))
(newState, Some(HardCodedGrammar(newState)))
}
}
}
class Partition {
def restrictTo(subset: Set[Any]): Partition = ???
}
class PartitionBlock {}
class PrefixTreeFactory {
def makePrefixTree(ℒ: Language): AngluinAcceptor = ???
}
case class Quotient(A: AngluinAcceptor, π: Partition) {
def evaluate: AngluinAcceptor = ???
}
// implicit def enAlphabet(symbols: Set[Symbol]): Alphabet = Alphabet(symbols)
case class Alphabet(symbols: Set[Symbol])
// implicit def enText(expressions: Iterable[Iterable[Symbol]]): Text = Text(expressions)
case class Text(expressions: Iterable[Iterable[Symbol]]) {
// def addExpression(s: List[Symbol]): Unit = expressions = expressions ::: List(s)
def length: Int = expressions.size
def isFor(ℒ: Language) = content === ℒ
def content: Language = new Language(expressions.filter(_ != ♯))
override def toString: String = "<" + expressions.mkString(", ") + ">"
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy