001: // This file is part of KeY - Integrated Deductive Software Design
002: // Copyright (C) 2001-2007 Universitaet Karlsruhe, Germany
003: // Universitaet Koblenz-Landau, Germany
004: // Chalmers University of Technology, Sweden
005: //
006: // The KeY system is protected by the GNU General Public License.
007: // See LICENSE.TXT for details.
008: //
009: //
010:
011: package de.uka.ilkd.key.logic.op.oclop;
012:
013: import de.uka.ilkd.key.logic.Name;
014: import de.uka.ilkd.key.logic.Term;
015: import de.uka.ilkd.key.logic.op.TermSymbol;
016: import de.uka.ilkd.key.logic.sort.Sort;
017: import de.uka.ilkd.key.logic.sort.oclsort.CollectionSort;
018: import de.uka.ilkd.key.logic.sort.oclsort.OclSort;
019:
020: /**
021: * Represents the OCL operation: union()
022: */
023: public class OclUnion extends TermSymbol {
024:
025: public OclUnion() {
026: super (new Name("$union"), OclSort.COLLECTION_OF_OCLANY);
027: }
028:
029: /** @return arity of the Function as int */
030: public int arity() {
031: return 2;
032: }
033:
034: /*
035: * checks if the given term is syntactically valid at its top
036: * level assumed the top level operator were this, i.e. if the
037: * direct subterms can be subterms of a term with this top level
038: * operator, the method returns true. Furthermore, it is checked
039: * that no variables are bound for none of the subterms.
040: * @param the Term to be checked.
041: * @return true iff the given term has
042: * subterms that are suitable for this function.
043: */
044: public boolean validTopLevel(Term term) {
045: if (term.arity() != arity()) {
046: return false;
047: }
048: if (!(term.sub(0).sort() instanceof CollectionSort)
049: || !(term.sub(1).sort() instanceof CollectionSort)) {
050: return false;
051: }
052: CollectionSort collSort0 = (CollectionSort) term.sub(0).sort();
053: CollectionSort collSort1 = (CollectionSort) term.sub(1).sort();
054: if ((collSort0.getCollectionKind() == CollectionSort.SEQUENCE && collSort1
055: .getCollectionKind() != CollectionSort.SEQUENCE)
056: || (collSort0.getCollectionKind() != CollectionSort.SEQUENCE && collSort1
057: .getCollectionKind() == CollectionSort.SEQUENCE)) {
058: return false;
059: }
060: if (!collSort0.getElemSort().extendsTrans(
061: collSort1.getElemSort())
062: && !collSort1.getElemSort().extendsTrans(
063: collSort0.getElemSort())) {
064: return false;
065: }
066: return true;
067: }
068:
069: public Sort sort(Term[] subTerm) {
070: if (subTerm.length != arity()) {
071: throw new IllegalArgumentException(
072: "Cannot determine sort of "
073: + "invalid term (Wrong arity).");
074: }
075: if (!(subTerm[0].sort() instanceof CollectionSort)
076: || !(subTerm[1].sort() instanceof CollectionSort)) {
077: throw new IllegalArgumentException(
078: "Cannot determine sort of "
079: + "invalid term (Both args must be Collections).");
080: }
081:
082: int resultCollKind = -1;
083: int collKind0 = ((CollectionSort) subTerm[0].sort())
084: .getCollectionKind();
085: int collKind1 = ((CollectionSort) subTerm[1].sort())
086: .getCollectionKind();
087: if (collKind0 == CollectionSort.SET
088: && collKind1 == CollectionSort.SET) {
089: resultCollKind = CollectionSort.SET;
090: } else if (collKind0 == CollectionSort.BAG
091: || collKind1 == CollectionSort.BAG) {
092: resultCollKind = CollectionSort.BAG;
093: } else if (collKind0 == CollectionSort.SEQUENCE
094: && collKind1 == CollectionSort.SEQUENCE) {
095: resultCollKind = CollectionSort.SEQUENCE;
096: } else {
097: throw new IllegalArgumentException(
098: "Cannot determine sort of invalid term\n"
099: + "(Operator not defined on these Collection sorts).");
100: }
101:
102: OclSort resultElemSort = null;
103: OclSort elemSort0 = ((CollectionSort) subTerm[0].sort())
104: .getElemSort();
105: OclSort elemSort1 = ((CollectionSort) subTerm[1].sort())
106: .getElemSort();
107: if (elemSort0.extendsTrans(elemSort1)) {
108: resultElemSort = elemSort1;
109: } else if (elemSort1.extendsTrans(elemSort0)) {
110: resultElemSort = elemSort0;
111: } else {
112: throw new IllegalArgumentException(
113: "Cannot determine sort of "
114: + "invalid term (Arguments must have a common supersort).");
115: }
116:
117: return CollectionSort.getCollectionSort(resultCollKind,
118: resultElemSort);
119: }
120:
121: public String toString() {
122: return (name() + ":" + OclSort.OCLGENERIC);
123: }
124:
125: public String proofToString() {
126: String s = OclSort.OCLGENERIC + " " + name();
127: s += "(" + OclSort.BOOLEAN + "," + OclSort.OCLGENERIC + ","
128: + OclSort.OCLGENERIC;
129: s += ");\n";
130: return s;
131: }
132: }
|