Skip to content
This repository was archived by the owner on Feb 19, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Refactor util.Optional as a wrapper of scala.Option.
  • Loading branch information
Giulio De Luise committed Apr 22, 2015
commit 20172648be708d7ea768920cc77697b6c0831dba
6 changes: 3 additions & 3 deletions src/main/scala/epic/parser/models/NeuralModel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import java.io.File
import epic.parser.projections.GrammarRefinements
import epic.constraints.ChartConstraints.Factory
import epic.constraints.ChartConstraints
import epic.util.{NotProvided, Optional}
import epic.util.Optional

case class NeuralModelFactory(@Help(text=
"""The kind of annotation to do on the refined grammar. Default uses no annotations.
Expand All @@ -30,8 +30,8 @@ You can also epic.trees.annotations.KMAnnotator to get more or less Klein and Ma
oldWeights: File = null,
numOutputs: Int = 100,
numHidden: Int = 100,
posFeaturizer: Optional[WordFeaturizer[String]] = NotProvided,
spanFeaturizer: Optional[SplitSpanFeaturizer[String]] = NotProvided,
posFeaturizer: Optional[WordFeaturizer[String]] = None,
spanFeaturizer: Optional[SplitSpanFeaturizer[String]] = None,
useIdentitySurfaceFeatures: Boolean = false) extends ParserExtractableModelFactory[AnnotatedLabel, String] {
type MyModel = TransformModel[AnnotatedLabel, AnnotatedLabel, String]

Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/epic/parser/models/ParserTrainer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import breeze.optimize.FirstOrderMinimizer.OptParams
import epic.parser.ParseEval.Statistics
import epic.features.LongestFrequentSuffixFeaturizer.LongestFrequentSuffix
import epic.features.LongestFrequentSuffixFeaturizer

import epic.util.Optional

/**
* The main entry point for training discriminative parsers.
Expand Down
8 changes: 4 additions & 4 deletions src/main/scala/epic/parser/models/SpanModel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,8 @@ You can also epic.trees.annotations.KMAnnotator to get more or less Klein and Ma
useGrammar: Boolean = true,
useFullShape: Boolean = false,
useSplitShape: Boolean = false,
posFeaturizer: Optional[WordFeaturizer[String]] = NotProvided,
spanFeaturizer: Optional[SplitSpanFeaturizer[String]] = NotProvided,
posFeaturizer: Optional[WordFeaturizer[String]] = None,
spanFeaturizer: Optional[SplitSpanFeaturizer[String]] = None,
extraParams: ExtraParams = ExtraParams()) extends ParserModelFactory[AnnotatedLabel, String] with SafeLogging {

type MyModel = SpanModel[AnnotatedLabel, AnnotatedLabel, String]
Expand Down Expand Up @@ -619,8 +619,8 @@ object SpanModelFactory {

def buildSimple(trees: IndexedSeq[TreeInstance[AnnotatedLabel, String]],
annotator: TreeAnnotator[AnnotatedLabel, String, AnnotatedLabel] = GenerativeParser.defaultAnnotator(),
posFeaturizer: Optional[WordFeaturizer[String]] = NotProvided,
spanFeaturizer: Optional[SplitSpanFeaturizer[String]] = NotProvided,
posFeaturizer: Optional[WordFeaturizer[String]] = None,
spanFeaturizer: Optional[SplitSpanFeaturizer[String]] = None,
opt: OptParams = OptParams())(implicit cache: CacheBroker) = {
val (topo, lexicon) = XbarGrammar().xbarGrammar(trees)
val initialParser = GenerativeParser.annotatedParser(topo, lexicon, annotator, trees)
Expand Down
6 changes: 3 additions & 3 deletions src/main/scala/epic/parser/models/ThreePointModel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import epic.parser.projections.GrammarRefinements
import epic.preprocess.MLSentenceSegmenter.BiasFeature
import epic.trees.annotations.TreeAnnotator
import epic.trees._
import epic.util.{NotProvided, Optional, LRUCache}
import epic.util.{Optional, LRUCache}

/**
* TODO
Expand Down Expand Up @@ -305,8 +305,8 @@ You can also epic.trees.annotations.KMAnnotator to get more or less Klein and Ma
maxNGramOrder:Int = 2,
useGrammar: Boolean = true,
rank: Int = 1,
posFeaturizer: Optional[WordFeaturizer[String]] = NotProvided,
spanFeaturizer: Optional[SplitSpanFeaturizer[String]] = NotProvided,
posFeaturizer: Optional[WordFeaturizer[String]] = None,
spanFeaturizer: Optional[SplitSpanFeaturizer[String]] = None,
extraParams: ExtraParams = ExtraParams()) extends ParserModelFactory[AnnotatedLabel, String] {

type MyModel = ThreePointModel[AnnotatedLabel, AnnotatedLabel, String]
Expand Down
6 changes: 3 additions & 3 deletions src/main/scala/epic/parser/models/TransformModel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import epic.lexicon.Lexicon
import epic.parser.projections.GrammarRefinements
import epic.trees._
import epic.trees.annotations.TreeAnnotator
import epic.util.{LRUCache, NotProvided, Optional}
import epic.util.{LRUCache, Optional}

/**
* TODO
Expand Down Expand Up @@ -225,8 +225,8 @@ You can also epic.trees.annotations.KMAnnotator to get more or less Klein and Ma
maxNGramOrder:Int = 2,
useGrammar: Boolean = true,
rank: Int = 1,
posFeaturizer: Optional[WordFeaturizer[String]] = NotProvided,
spanFeaturizer: Optional[SplitSpanFeaturizer[String]] = NotProvided,
posFeaturizer: Optional[WordFeaturizer[String]] = None,
spanFeaturizer: Optional[SplitSpanFeaturizer[String]] = None,
extraParams: ExtraParams = ExtraParams()) extends ParserModelFactory[AnnotatedLabel, String] {

type MyModel = TransformModel[AnnotatedLabel, AnnotatedLabel, String]
Expand Down
8 changes: 4 additions & 4 deletions src/main/scala/epic/parser/projections/OracleParser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import epic.constraints.{CachedChartConstraintsFactory, ChartConstraints}
import epic.trees._
import epic.parser._
import breeze.numerics.I
import epic.util.{NotProvided, Optional, SafeLogging, CacheBroker}
import epic.util.{Optional, SafeLogging, CacheBroker}
import epic.parser.GrammarAnchoring.StructureDelegatingAnchoring
import breeze.config.{Configuration, CommandLineParser, Help}
import java.io.File
Expand Down Expand Up @@ -40,7 +40,7 @@ import epic.constraints.ChartConstraints.UnifiedFactory
*
* @author dlwh
*/
class OracleParser[L, L2, W](val grammar: SimpleGrammar[L, L2, W], backupGrammar: Optional[SimpleGrammar[L, L2, W]] = NotProvided) extends SafeLogging {
class OracleParser[L, L2, W](val grammar: SimpleGrammar[L, L2, W], backupGrammar: Optional[SimpleGrammar[L, L2, W]] = None) extends SafeLogging {
private val cache = CacheBroker().make[IndexedSeq[W], BinarizedTree[L2]]("OracleParser")

private var problems = 0
Expand All @@ -66,7 +66,7 @@ class OracleParser[L, L2, W](val grammar: SimpleGrammar[L, L2, W], backupGrammar
f"Gold tree for $words not reachable. $ratio%.2f are bad so far. "
}

(IndexedSeq(grammar) ++ backupGrammar.iterator).iterator.map { grammar =>
(IndexedSeq(grammar) ++ backupGrammar.iterator).iterator.flatMap { grammar =>
try {
val w = words
val marg = makeGoldPromotingAnchoring(grammar, w, tree, treeconstraints, constraints).maxMarginal
Expand All @@ -83,7 +83,7 @@ class OracleParser[L, L2, W](val grammar: SimpleGrammar[L, L2, W], backupGrammar
} catch {
case ex: ParseExtractionException => None
}
}.flatten.next()
}.next()

} catch {
case ex:NoSuchElementException =>
Expand Down
6 changes: 3 additions & 3 deletions src/main/scala/epic/sequences/CRF.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import java.util
import collection.mutable.ArrayBuffer
import breeze.features.FeatureVector
import epic.constraints.{LabeledSpanConstraints, TagConstraints}
import epic.util.{NotProvided, Optional, CacheBroker}
import epic.util.{Optional, CacheBroker}
import breeze.optimize.FirstOrderMinimizer.OptParams
import breeze.optimize.CachedBatchDiffFunction
import epic.features.WordFeaturizer
Expand Down Expand Up @@ -58,8 +58,8 @@ object CRF {
def buildSimple[L](data: IndexedSeq[TaggedSequence[L, String]],
startSymbol: L,
gazetteer: Gazetteer[Any, String] = Gazetteer.empty[Any, String],
wordFeaturizer: Optional[WordFeaturizer[String]] = NotProvided,
transitionFeaturizer: Optional[WordFeaturizer[String]] = NotProvided,
wordFeaturizer: Optional[WordFeaturizer[String]] = None,
transitionFeaturizer: Optional[WordFeaturizer[String]] = None,
opt: OptParams = OptParams(),
hashFeatures: Double = 1.0)(implicit cache: CacheBroker = CacheBroker()):CRF[L, String] = {
val model: CRFModel[L, String] = new TaggedSequenceModelFactory[L](startSymbol, gazetteer = gazetteer, wordFeaturizer = wordFeaturizer, transitionFeaturizer = transitionFeaturizer, hashFeatureScale = hashFeatures).makeModel(data)
Expand Down
8 changes: 4 additions & 4 deletions src/main/scala/epic/sequences/CRFModel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import breeze.features.FeatureVector
import epic.features._
import epic.lexicon.SimpleLexicon
import java.util
import epic.util.{ProgressLog, SafeLogging, NotProvided, Optional}
import epic.util.{ProgressLog, SafeLogging, Optional}
import epic.constraints.TagConstraints

/**
Expand Down Expand Up @@ -134,9 +134,9 @@ class CRFInference[L, W](val weights: DenseVector[Double],
}

class TaggedSequenceModelFactory[L](val startSymbol: L,
gazetteer: Optional[Gazetteer[Any, String]] = NotProvided,
wordFeaturizer: Optional[WordFeaturizer[String]] = NotProvided,
transitionFeaturizer: Optional[WordFeaturizer[String]] = NotProvided,
gazetteer: Optional[Gazetteer[Any, String]] = None,
wordFeaturizer: Optional[WordFeaturizer[String]] = None,
transitionFeaturizer: Optional[WordFeaturizer[String]] = None,
weights: Feature=>Double = { (f:Feature) => 0.0},
hashFeatureScale: Double = 0.0) extends SafeLogging {

Expand Down
6 changes: 3 additions & 3 deletions src/main/scala/epic/sequences/SemiCRF.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import breeze.optimize.CachedBatchDiffFunction
import breeze.linalg.{softmax, DenseVector}
import epic.constraints.{TagConstraints, LabeledSpanConstraints}
import epic.constraints.LabeledSpanConstraints.NoConstraints
import epic.util.{NotProvided, Optional}
import epic.util.Optional
import epic.features.{WordFeaturizer, SurfaceFeaturizer}

/**
Expand Down Expand Up @@ -51,8 +51,8 @@ object SemiCRF {

def buildSimple[L](data: IndexedSeq[Segmentation[L, String]],
gazetteer: Gazetteer[Any, String] = Gazetteer.empty[Any, String],
wordFeaturizer: Optional[WordFeaturizer[String]] = NotProvided,
spanFeaturizer: Optional[SurfaceFeaturizer[String]] = NotProvided,
wordFeaturizer: Optional[WordFeaturizer[String]] = None,
spanFeaturizer: Optional[SurfaceFeaturizer[String]] = None,
opt: OptParams = OptParams(regularization = 1.0)):SemiCRF[L, String] = {
val model: SemiCRFModel[L, String] = new SegmentationModelFactory[L](gazetteer = gazetteer, wordFeaturizer = wordFeaturizer, spanFeaturizer = spanFeaturizer).makeModel(data)

Expand Down
10 changes: 5 additions & 5 deletions src/main/scala/epic/sequences/SemiCRFModel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import epic.framework._
import epic.lexicon.SimpleLexicon
import epic.sequences.SemiCRF.{IdentityAnchoring, TransitionVisitor}
import epic.sequences.SemiCRFModel.BIEOFeatureAnchoring
import epic.util.{NotProvided, Optional, SafeLogging}
import epic.util.{Optional, SafeLogging}

import scala.collection.mutable.ArrayBuffer

Expand Down Expand Up @@ -227,10 +227,10 @@ class SemiCRFInference[L, W](weights: DenseVector[Double],
* @param weights
* @tparam L
*/
class SegmentationModelFactory[L](wordFeaturizer: Optional[WordFeaturizer[String]] = NotProvided,
spanFeaturizer: Optional[SurfaceFeaturizer[String]] = NotProvided,
pruningModel: Optional[SemiCRF.ConstraintSemiCRF[L, String]] = NotProvided,
gazetteer: Optional[Gazetteer[Any, String]] = NotProvided,
class SegmentationModelFactory[L](wordFeaturizer: Optional[WordFeaturizer[String]] = None,
spanFeaturizer: Optional[SurfaceFeaturizer[String]] = None,
pruningModel: Optional[SemiCRF.ConstraintSemiCRF[L, String]] = None,
gazetteer: Optional[Gazetteer[Any, String]] = None,
weights: Feature=>Double = { (f:Feature) => 0.0}) extends LazyLogging {

import epic.sequences.SegmentationModelFactory._
Expand Down
71 changes: 10 additions & 61 deletions src/main/scala/epic/util/Optional.scala
Original file line number Diff line number Diff line change
@@ -1,71 +1,20 @@
package epic.util

/**
* Optional is just like [[scala.Option]], except that we offer implicit
* conversion from the Optional to Provided. Mostly for use in optional argument lists
* @author dlwh
* Optional is a wrapper of [[scala.Option]] with an implicit conversion from Any to Optional.
* Mostly for use in optional argument lists.
* @author dlwh, jovilius
*/
sealed trait Optional[+A] {
def iterator: Iterator[A] = this match {
case Provided(a) => Iterator(a)
case NotProvided => Iterator.empty
}

def get: A
def isEmpty: Boolean = this eq NotProvided
def size : Int = if(isEmpty) 0 else 1

def map[B](f: A=>B): Optional[B] = this match {
case Provided(x) => Provided(f(x))
case NotProvided => NotProvided
}

def flatMap[B](f: A=>Optional[B]) = this match {
case Provided(x) => f(x)
case NotProvided => NotProvided
}


def foreach[B](f: A=>B) {
this match {
case Provided(x) => f(x)
case _ =>
}
}

def foldLeft[B](b:B)(f: (B,A) => B) = if(isEmpty) b else f(b, get)

def fold[B](ifSome: A => B , ifNone: => B) = if(isEmpty) ifNone else ifSome(get)

def getOrElse[B>:A](ifNone: => B) = if(isEmpty) ifNone else get
case class Optional[+A](value: Option[A]) {
def foldLeft[B](b: B)(f: (B, A) => B) = value.fold(b)(x => f(b, x))
}

/**
* Equivalent to Some, but with an implicit conversion
* from A to Provided(aA
* @param get
* @tparam A
*/
case class Provided[+A](get: A) extends Optional[A] {
}

/**
* Equivalent to None
*/
@SerialVersionUID(-649101350749082174L)
case object NotProvided extends Optional[Nothing] {
def get = throw new NoSuchElementException("NotProvided.get")
}
object Optional {

implicit def anyToOptional[A](x: A): Optional[A] = if (x == null) Optional(None) else Optional(Some(x))

object Optional extends LowPriorityOptionalImplicit {
implicit def liftOption[A](o: Option[A]) = o match {
case Some(a) => Provided(a)
case None => NotProvided
}

}
implicit def optionToOptional[A](x: Option[A]): Optional[A] = Optional(x)

sealed trait LowPriorityOptionalImplicit {
implicit def liftAnything[A](a: A) = if(a == null) NotProvided else Provided(a)
implicit def optionalToOption[A](x: Optional[A]): Option[A] = x.value

}