/*
* The base class of a property lattice.
*
* Copyright (c) 2007-2009 The Regents of the University of California. All
* rights reserved. Permission is hereby granted, without written agreement and
* without license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the above
* copyright notice and the following two paragraphs appear in all copies of
* this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
* "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* PT_COPYRIGHT_VERSION_2 COPYRIGHTENDKEY
*
*/
package ptolemy.data.ontologies;
import java.util.HashMap;
import ptolemy.data.properties.Property;
import ptolemy.graph.DirectedAcyclicGraph;
import ptolemy.graph.Node;
import ptolemy.kernel.util.IllegalActionException;
//////////////////////////////////////////////////////////////////////////////
//// ConceptLattice
/** A data structure defining an ontology that is constrained to have the
* structure of a mathematical lattice. A lattice is a partially ordered
* set where every subset has a least upper bound and a greatest lower bound.
* A concept lattice is a lattice
* where the elements of the set are instances of {@link Concept}.
* We represent a concept lattice as a directed acyclic graph.
*
* @author Thomas Mandl, Man-Kit Leung, Edward A. Lee, Ben Lickly, Dai Bui, Christopher Brooks
* @version $Id$
* @since Ptolemy II 7.1
* @Pt.ProposedRating Red (mankit)
* @Pt.AcceptedRating Red (mankit)
* @see ptolemy.graph.CPO
*/
public class ConceptLattice extends DirectedAcyclicGraph {
///////////////////////////////////////////////////////////////////
//// public methods ////
/**
* Add the specified element to this lattice. The element is assumed to be a
* LatticeProperty. Otherwise, a runtime exception would occur.
* @param weight The element.
* @return The constructed graph node in the lattice.
*/
public Node addNodeWeight(Object weight) {
// The weight argument must be Object or else we get test failures
_propertyMap.put(weight.toString().toUpperCase(),
(Concept) weight);
return super.addNodeWeight(weight);
}
/**
* Add structured properties. The parameter flag is a bit-wise OR union of
* the structured properties desired to add. The class provides a set of
* symbolic constants for these structured property types. For example,
* invoke addStructuredProperties(RECORD) to add the RecordProperty. This
* method should be called after all base elements have been added. The user
* is responsible for ensuring a lattice structure before calling this
* method. The lattice structure should be preserved after calling this
* method, so there is no need to do another check.
* @param structuredPropertiesToAdd The bit-wise OR union of the structured
* properties desired to add.
* @throws IllegalActionException
*/
/* FIXME
public void addStructuredProperties(int structuredPropertiesToAdd)
throws IllegalActionException {
if ((structuredPropertiesToAdd & RECORD) != 0) {
Property record = new RecordProperty(this, new String[0],
new LatticeProperty[0]).getRepresentative();
if (!isLattice()) {
throw new IllegalActionException(
"This ontology needs to be a lattice "
+ "before adding structured types.");
}
Object bottom = bottom();
Object top = top();
addNodeWeight(record);
addEdge(bottom, record);
addEdge(record, top);
}
if ((structuredPropertiesToAdd & ARRAY) != 0) {
// FIXME: add Array structure.
}
}
*/
/**
* Compare two properties in the property lattice. The arguments must be
* instances of Property, otherwise an exception will be thrown. This method
* returns one of ptolemy.graph.CPO.LOWER, ptolemy.graph.CPO.SAME,
* ptolemy.graph.CPO.HIGHER, ptolemy.graph.CPO.INCOMPARABLE, indicating the
* first argument is lower than, equal to, higher than, or incomparable with
* the second argument in the property hierarchy, respectively.
* @param t1 an instance of Property.
* @param t2 an instance of Property.
* @return An integer.
* @exception IllegalArgumentException If one or both arguments are not
* instances of Property.
*/
public int compare(Object t1, Object t2) {
synchronized (ConceptLattice.class) {
if (!(t1 instanceof Property) || !(t2 instanceof Property)) {
throw new IllegalArgumentException("PropertyLattice.compare: "
+ "Arguments are not instances of Property: "
+ " property1 = " + t1 + ", property2 = " + t2);
}
Property t1Rep = _toRepresentative((Property) t1);
Property t2Rep = _toRepresentative((Property) t2);
/* FIXME
if (t1Rep.equals(t2Rep) && t1Rep instanceof StructuredProperty) {
return ((StructuredProperty) t1)
._compare((StructuredProperty) t2);
}
*/
return super.compare(t1Rep, t2Rep);
}
}
/**
* Return the element associated with the specified name.
* @param elementName The specified name.
* @return The element.
* @throws IllegalActionException Thrown if this lattice does not contain
* the element with the specified name.
*/
public Concept getElement(String elementName)
throws IllegalActionException {
Concept property = _propertyMap.get(elementName.toUpperCase());
if (property == null) {
throw new IllegalActionException("No lattice element named \""
+ elementName + "\".");
}
return property;
}
/**
* Return the name of this lattice.
* @return The name of this lattice, which is the name of the package.
*/
public String getName() {
return toString();
}
/**
* Return true.
* @return true.
*/
public boolean isLattice() {
return true;
}
/** Return the name of the package that contains this class.
* @return the name of the package that contains this class.
*/
public String toString() {
String name = getClass().getPackage().getName();
return name.substring(name.lastIndexOf('.') + 1);
}
///////////////////////////////////////////////////////////////////
//// public fields ////
/**
* Public symbolic constant value for the RecordProperty.
*/
public final int RECORD = 0x1;
/**
* Public symbolic constant value for the ArrayProperty.
*/
public final int ARRAY = 0x10;
///////////////////////////////////////////////////////////////////
//// private methods ////
// If the argument is a structured type, return its representative;
// otherwise, return the argument. In the latter case, the argument
// is either a base type or a user defined type that is not a
// structured type.
private Property _toRepresentative(Property p) {
/* FIXME
if (p instanceof StructuredProperty) {
return ((StructuredProperty) p).getRepresentative();
} else {
return p;
}
*/
return p;
}
///////////////////////////////////////////////////////////////////
//// private fields ////
private final HashMap<String, Concept> _propertyMap = new HashMap<String, Concept>();
}