Skip to content

Commit

Permalink
fix all test errors caused by lack of ordering
Browse files Browse the repository at this point in the history
  • Loading branch information
tribbloid committed Feb 10, 2024
1 parent facfc64 commit dc6d80c
Show file tree
Hide file tree
Showing 40 changed files with 808 additions and 777 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.tribbloids.spookystuff.utils
import com.tribbloids.spookystuff.tree.TreeView
import com.tribbloids.spookystuff.utils.TreeThrowable.ExceptionWithCauses

import scala.util.control.NoStackTrace
import scala.util.{Failure, Success, Try}

object TreeThrowable {
Expand Down Expand Up @@ -151,6 +152,7 @@ object TreeThrowable {
protected case class ExceptionWithCauses(
override val causes: Seq[Throwable] = Nil
) extends Exception
with NoStackTrace
with TreeThrowable {

override def getCause: Throwable = causes.headOption.orNull
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.tribbloids.spookystuff.utils.data

import ai.acyclic.prover.commons.same.EqualBy
import org.apache.spark.ml.dsl.utils.?

import scala.util.Try

trait AttrLike[T] extends Serializable with EqualBy {

def name: String
def aliases: List[String]

final lazy val allNames: Seq[String] = (Seq(name) ++ aliases).distinct

def ->(v: T): Magnets.AttrValueMag[T] = {

Magnets.AttrValueMag[T](this.name, Some(v))
}

def -?>(vOpt: T `?` _): Magnets.AttrValueMag[T] = {

Magnets.AttrValueMag[T](this.name, vOpt.asOption)
}

def tryGet: Try[T]

final def get: Option[T] = tryGet.toOption
final def value: T = tryGet.get

override def samenessDelegatedTo: Any = this.allNames -> get
}

object AttrLike {

// implicit def toV[T](attr: AttrLike[T]): T = attr.value
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
package com.tribbloids.spookystuff.utils.data

import ai.acyclic.prover.commons.same.EqualBy
import com.tribbloids.spookystuff.relay.RootTagged
import com.tribbloids.spookystuff.relay.xml.Xml
import com.tribbloids.spookystuff.utils.{CommonUtils, TreeThrowable}
import org.apache.spark.ml.dsl.utils.{?, HasEagerInnerObjects}

import java.util.Properties
import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer
import scala.language.implicitConversions
import scala.util.Try

/**
* entity-(with)-attribute-value
*/
trait EAVLike extends HasEagerInnerObjects with EqualBy with RootTagged with Serializable {

def internal: collection.Map[String, Any]

def system: EAVSystem

override def rootTag: String = Xml.ROOT

protected def getLookup: Map[String, Any] = internal.toMap
@transient final lazy val lookup = getLookup

@transient private lazy val providedHintStr: Option[String] = {
if (lookup.isEmpty) {
None
} else {
Some(s"only ${KVs.raw.map(_._1).mkString(", ")} are provided")
}
}

def tryGet(k: String, nullable: Boolean = false): Try[Any] = Try {
val result = lookup.getOrElse(
k,
throw new UnsupportedOperationException(
(
Seq(
s"Parameter $k is missing"
) ++ providedHintStr
).mkString("\n")
)
)
if (!nullable) require(result != null, s"null value for `$k`")
result
}

def get(k: String, nullable: Boolean = false): Option[Any] = tryGet(k, nullable).toOption

def contains(k: String): Boolean = tryGet(k).isSuccess

override def toString: String = KVs.raw.mkString("[", ", ", "]")

/**
* by default, declared [[Attr]] will be listed in their order of declaration, then non-declared KVs ordered by keys
*/
@transient object KVs {

requireInitialised()

lazy val raw: Seq[(String, Any)] = internal.toSeq.sortBy(_._1)

lazy val (declared: Vector[(String, Option[Any])], others: Vector[(String, Option[Any])]) = {

var map = lookup

val declared = Attr.declared.toVector.map { attr =>
attr.allNames.foreach { name =>
map = map.removed(name)
}
attr.name -> attr.get
}

val others = map.keys.toVector.sorted.map { k =>
k -> lookup.get(k)
}

declared -> others
}

lazy val all: Vector[(String, Option[Any])] = declared ++ others

lazy val defined: Vector[(String, Any)] = {
all
.collect {
case (k, Some(v)) => k -> v
}
}
}

@transient protected lazy val sortEvidence: Seq[String] = {

val result = KVs.declared.map(v => v._2.map(_.toString).orNull)
result
}
override def samenessDelegatedTo: Any = sortEvidence

@transient lazy val asProperties: Properties = {
val properties = new Properties()

KVs.defined
.foreach { v =>
properties.put(v._1, v._2)
}

properties
}

// def attr(v: String): Attr[Any] = new Attr[Any](primaryNameOverride = v)

@transient object Attr {

lazy val declared: ArrayBuffer[Attr[_]] = ArrayBuffer.empty

lazy val nameToAttrMap: mutable.Map[String, Attr[_]] = mutable.Map.empty

def +=(v: Attr[_]): Unit = {
declared += v
v.allNames.foreach { name =>
nameToAttrMap.updateWith(name) {
case Some(existing) =>
throw new UnsupportedOperationException(s"Attribute $name is already defined in ${existing}")
case None =>
Some(v)
}
}

}
}

trait Accessor[T] {

protected def compute: T
private lazy val get: T = compute

def tryGet: Try[T] = Try(get)
}

abstract class Attr[T]( // has to be declared in the EAVLike
// should only be used in setters
val aliases: List[String] = Nil,
nullable: Boolean = false,
default: T `?` _ = None,
nameOverride: String `?` _ = None
)(
implicit
ev: T <:< Any
) extends AttrLike[T]
with EagerInnerObject
with Accessor[T]
with Product {

{
Attr.declared += this
}

override def toString: String = {
throw new UnsupportedOperationException(
"Attribute cannot be used as string, please use primaryName or value instead"
)
}

def outer: EAVLike = EAVLike.this

final def name: String = nameOverride.getOrElse(productPrefix)

override def compute: T = {

val getExplicits: Seq[() => T] = allNames.map { name =>
{ () =>
outer.tryGet(name, nullable).get.asInstanceOf[T]
}
}

val getDefault = { () =>
default.getOrElse {
throw new UnsupportedOperationException(s"Undefined default value for $name")
}
}

TreeThrowable
.|||^(getExplicits :+ getDefault)
.get

}

case class asEnum[EE <: Enumeration](enum: EE)(
implicit
ev: T <:< String
) extends Accessor[EE#Value] {

override protected def compute: EE#Value = {

val v = Attr.this.value

val result = enum.withName(ev(v))

result
}
}

case class asBool()(
implicit
ev: T <:< String
) extends Accessor[Boolean] {

override protected def compute: Boolean = {

val v = Attr.this.value

CommonUtils.tryParseBoolean(v).get
}
}

case class asInt()(
implicit
ev: T <:< String
) extends Accessor[Int] {

override protected def compute: Int = {

val v = Attr.this.value

ev(v).toInt
}
}
}
}

object EAVLike {

implicit def toOps[T <: EAVLike](v: T): EAVOps[T] = EAVOps(v)(v.system.asInstanceOf[EAVSystem.Aux[T]])
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package org.apache.spark.ml.dsl.utils.data
package com.tribbloids.spookystuff.utils.data

import com.tribbloids.spookystuff.utils.CommonUtils

case class EAVOps[T <: EAV](self: T)(
case class EAVOps[T <: EAVLike](self: T)(
implicit
val sys: EAVSystem.Aux[T]
) {
Expand All @@ -12,7 +12,7 @@ case class EAVOps[T <: EAV](self: T)(
*/
def :++(that: T): T = {

sys._EAV(CommonUtils.mergePreserveOrder(self.internal, that.internal))
sys.^(CommonUtils.mergePreserveOrder(self.internal, that.internal))
}

/**
Expand All @@ -27,11 +27,11 @@ case class EAVOps[T <: EAV](self: T)(
that: T
): T = {

val _include: List[String] = (self.asMap.keys ++ that.asMap.keys).toList
val _include: List[String] = (self.lookup.keys ++ that.lookup.keys).toList

val result = _include.flatMap { key =>
val vs = Seq(self, that).map { v =>
v.asMap.get(key)
v.lookup.get(key)
}.flatten

val mergedOpt = vs match {
Expand All @@ -50,11 +50,11 @@ case class EAVOps[T <: EAV](self: T)(
sys.From.tuple(result: _*)
}

def updated(kvs: Magnets.AttrValueMag[self.Bound]*): T = {
def updated(kvs: Magnets.AttrValueMag[Any]*): T = {
++:(sys.From(kvs: _*))
}

def drop(vs: Magnets.AttrMag*): T = sys.From.iterable(self.asMap -- vs.flatMap(_.names))
def drop(vs: Magnets.AttrMag*): T = sys.From.iterable(self.lookup -- vs.flatMap(_.names))

def dropAll(vs: Iterable[Magnets.AttrMag]): T = drop(vs.toSeq: _*)

Expand Down
Loading

0 comments on commit dc6d80c

Please sign in to comment.