com.uber.engsec.dp.dataflow.domain.DomainElement.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sql-differential-privacy Show documentation
Show all versions of sql-differential-privacy Show documentation
Differential privacy for SQL queries
The newest version!
/*
* Copyright (c) 2017 Uber Technologies, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.uber.engsec.dp.dataflow.domain
/** A monad for lattice values represented by type E augmented with (type-less) top and bottom elements.
*/
abstract class DomainElem[+E] {
/** Returns the element value, or throws java.util.NoSuchElementException if the lattice element is Top or Bottom
*/
def get: E
def isTop: Boolean
def isBottom: Boolean
/** Retrieves the lattice value as an option, with Bottom returning None and element type E returning Some(e).
* Should only be used on semi-bounded lattices which are guaranteed never to have value Top (e.g., SetLattice) since
* this will raise an exception.
*/
def asOption: Option[E]
}
case object Top extends DomainElem[Nothing] {
override def isTop: Boolean = true
override def isBottom: Boolean = false
override def asOption: Option[Nothing] = throw new java.util.NoSuchElementException("Top.asOption")
override def get = throw new java.util.NoSuchElementException("Top.get")
}
case object Bottom extends DomainElem[Nothing] {
override def isTop: Boolean = false
override def isBottom: Boolean = true
override def asOption: Option[Nothing] = None
override def get = throw new java.util.NoSuchElementException("Bottom.get")
}
/** External code shouldn't need to interact directly with this class; the implicit definitions below automatically
* convert to and from this wrapper and the underlying element type.
*/
case class Mid[E](value: E) extends DomainElem[E] {
override def isTop: Boolean = false
override def isBottom: Boolean = false
override def get: E = value
override def asOption: Option[E] = Some(value)
override def toString: String = value.toString
}
object DomainElem {
import scala.language.implicitConversions
implicit def val2DomainElem[E](value: E): DomainElem[E] = Mid(value)
implicit def elem2Val[E](value: Mid[E]): E = value.get
/** Convert from Option[E] to lattice element, with Option.None mapped to Bottom. */
implicit def option2DomainElem[E](value: Option[E]): DomainElem[E] = value.fold[DomainElem[E]](Bottom)(Mid(_))
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy