org.erights.e.elib.tables
Class FlexTrijection

java.lang.Object
  |
  +--org.erights.e.elib.tables.EMap
        |
        +--org.erights.e.elib.tables.FlexMap
              |
              +--org.erights.e.elib.tables.FlexTrijection
All Implemented Interfaces:
EPrintable, Iteratable, Marker, PassByProxy, Persistent, Serializable

public class FlexTrijection
extends FlexMap

Safe: A mutable single valued mapping whose <>trijective inverse is also a mutable single valued mapping.

Given two sets X and Y, a function f that maps from X to Y, and a function g that maps from Y to X; f and g are bijective inverses of each other iff

     for all x in X { g(f(x)) == x } &&
     for all y in Y { f(g(y)) == y }.
A Bijection is then a function whose bijective inverse that's also a Bijection.

We define here the related property that f and g are are trijective inverses iff

     for all x in X { f(g(f(x))) == f(x) } &&
     for all y in Y { g(f(g(y))) == g(y) }.
A Trijection is then a function whose trijective inverse is also a Trijection.

A FlexTrijection is a FlexMap you can ask for its inverse. The two FlexTrijection are facets on the same mutable state, so you can query and update this state through either or both. The facet representing f will operates on all of X as its domain, but only on that subset of Y that's in the range of f -- those y's in Y for which there's an x in X such that f(x) == y. Likewise, the facet representing g operated on all of Y as its domain, but only on that subset of X that's in the range of g.

A Trijection generally has many trijective inverses, but only has one minimal trijective inverse. g is a minimal trijective inverse of f if the domain of g is exactly the range of f. If f and g are both minimal trijective inverses of each other, then they are also bijective inverses.

The basic mutation operation on a FlexMap is f[x] := y. On a FlexTrijection, this also has the effect g[y] := x. If stores have only been performed on f but never on g, then g will be the minimal trijective inverse of f. If all stores have been performed only on f, and if all these stores have been strict, ie, of the form

f.put(x, y, true)
then f and g will be bijective inverses.

On a store, what actually gets stored is x and y after being coerced, which we call cx and cy. To avoid confusion, FlexTrijection arranges that each coercion happens once. Since cx and cy are both being used as keys they must both be settled. Where this isn't appropriate (as with the exit map), then TraversalKey should be used as a guard for the appropriate set.

Author:
Mark S. Miller, with thanks to Alan Karp and Norm Hardy
See Also:
Serialized Form

Field Summary
private  FlexMap myBackMap
           
private  ValueGuard myDomainGuard
           
private  FlexMap myForwardMap
           
private  FlexTrijection myInverse
           
private  ValueGuard myRangeGuard
           
(package private) static long serialVersionUID
           
 
Fields inherited from class org.erights.e.elib.tables.EMap
 
Fields inherited from interface org.erights.e.elib.serial.PassByProxy
HONORARY, HONORED_NAMES
 
Fields inherited from interface org.erights.e.elib.serial.Persistent
HONORARY, HONORED_NAMES
 
Constructor Summary
  FlexTrijection()
          Enabled: Defaults to :any, :any
  FlexTrijection(ValueGuard optDomainGuard, ValueGuard optRangeGuard)
          Enabled:
private FlexTrijection(ValueGuard domainGuard, ValueGuard rangeGuard, FlexMap forwardMap, FlexMap backMap, FlexTrijection inverse)
           
 
Method Summary
 Object get(Object key, Object instead)
          Enabled:
 FlexTrijection getInverse()
          Enabled:
 Object getKeys(Class type)
          Enabled:
 Object getValues(Class type)
          Enabled:
 Class keyType()
          Enabled: XXX This one is stupid until we generally shift from keyTypes to keyGuards.
 void put(Object key, Object value, boolean strict)
          Enabled: Store f[x] := y and g[y] := x If strict is true, it's more strict than the normal notion: it insists that both the key and value be unique in their columns.
 void removeAll()
          Enabled:
 void removeKey(Object key, boolean strict)
          Enabled: Removes g[f[x]] and f[x].
 int size()
          Enabled:
 Class valueType()
          Enabled: XXX This one is stupid until we generally shift from valueTypes to valueGuards.
 
Methods inherited from class org.erights.e.elib.tables.FlexMap
__optUncall, __printOn, clone, domain, fromColumns, fromPairs, fromTypes, fromTypes, interning, interning, make, make, put, putAll, putAll, readOnly, removeKey, removeKeys, removeKeys, snapshot
 
Methods inherited from class org.erights.e.elib.tables.EMap
and, butNot, contains, diverge, diverge, extract, get, getKeys, getPair, getPair, getValues, intersects, iterate, maps, optExtract, or, or, printOn, sortKeys, sortKeys, sortValues, sortValues, toString, with, without
 
Methods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

serialVersionUID

static final long serialVersionUID

myDomainGuard

private final ValueGuard myDomainGuard

myRangeGuard

private final ValueGuard myRangeGuard

myForwardMap

private final FlexMap myForwardMap

myBackMap

private final FlexMap myBackMap

myInverse

private final FlexTrijection myInverse
Constructor Detail

FlexTrijection

private FlexTrijection(ValueGuard domainGuard,
                       ValueGuard rangeGuard,
                       FlexMap forwardMap,
                       FlexMap backMap,
                       FlexTrijection inverse)
Parameters:
domainGuard -
rangeGuard -
forwardMap -
backMap -
inverse -

FlexTrijection

public FlexTrijection(ValueGuard optDomainGuard,
                      ValueGuard optRangeGuard)
Enabled:

Parameters:
optDomainGuard - defaults to :any
optRangeGuard - defaults to :any

FlexTrijection

public FlexTrijection()
Enabled: Defaults to :any, :any

Method Detail

put

public void put(Object key,
                Object value,
                boolean strict)
Enabled: Store f[x] := y and g[y] := x If strict is true, it's more strict than the normal notion: it insists that both the key and value be unique in their columns.

Specified by:
put in class FlexMap
Parameters:
key -
value -
strict -
See Also:
org.erights.e.elib.ref.Ref#isSettled

removeKey

public void removeKey(Object key,
                      boolean strict)
Enabled: Removes g[f[x]] and f[x].

Specified by:
removeKey in class FlexMap
Parameters:
key -
strict -

removeAll

public void removeAll()
Enabled:

Specified by:
removeAll in class FlexMap

size

public int size()
Enabled:

Specified by:
size in class EMap
Returns:

get

public Object get(Object key,
                  Object instead)
Enabled:

Specified by:
get in class EMap
Parameters:
key -
instead -
Returns:
See Also:
org.erights.e.elib.ref.Ref#isSettled

getKeys

public Object getKeys(Class type)
Enabled:

Specified by:
getKeys in class EMap
Parameters:
type -
Returns:

getValues

public Object getValues(Class type)
Enabled:

Specified by:
getValues in class EMap
Parameters:
type -
Returns:

keyType

public Class keyType()
Enabled: XXX This one is stupid until we generally shift from keyTypes to keyGuards.

Specified by:
keyType in class EMap
Returns:
Object.class

valueType

public Class valueType()
Enabled: XXX This one is stupid until we generally shift from valueTypes to valueGuards.

Specified by:
valueType in class EMap
Returns:
Object.class

getInverse

public FlexTrijection getInverse()
Enabled:

Returns:


comments?