This section describes the primitive functions built into the Acme predicate language for use in design invariants, heuristics, and analyses. The general form used for specifying function signatures is:
FunctionName(FormalParamName : FormalParamType ,*) : ReturnType
Followed by a description of the behavior of the function. Object is the most general type that can be used as a ReturnType or a formal parameter type. Design elements, design element types, properties, and representations are all subtypes of object. Primitive property values (integers, floats, booleans, and strings) are not objects and are not valid arguments to functions that take objects as arguments.
declaresType(e : Element, t : ElementType) : boolean
Returns true if element e declares that it satisfies type t, else
returns false.
satisfiesType(e : Element, t : ElementType) : boolean
Returns true if element e satisfies the predicate defined by type t,
independent of whether e declares to satisfy type t, else returns
false.
typesDeclared(e : Element) : set{Type}
Returns the set of identifiers of the types that element e declares
that it satisfies.
subtypeOf(subType,superType : ElementType) : boolean
Returns True if subType declares that it is a subtype of superType,
else returns False.
superTypes(t : ElementType) : set{Type}
Returns the set of all types that are declared as supertypes of element type t.
This function is applied recursively to t’s supertypes so that the
returned set contains all of t’s ancestors in the type hierarchy.
lookupType (a : Any, s : String): Type
Returns the type with the name s in the context a.
attached(conn : Connector, comp : Component) : boolean
Returns True if connector conn is attached to component comp,
else False.
attached(r : Role, p : Port) : boolean Returns True if role r is attached to port p, else False.
connected(c1, c2 : Component) :
boolean
Returns True if component c1 is directly connected to
component c2 by at least one connector, else False.
dangling (e: Element) : boolean
dangling takes a port or a role and returns true if that port or role is not attached to anything.
isInherited (p : Property) : boolean Returns true if the property is inherited from a declared type.
declaredIn (p : Property) : Element Returns the element that a property is declared in.
assignedIn (p : Property): Element Returns the element that a property is assigned in.
hasValue (p : Property) : boolean Returns true if the property has been assigned a value.
union (s1, s2 : Set{a}) : Set{a} Returns the union of sets s1 and s2.
intersection (s1, s2 : Set{a}) : Set{a} Returns the intersection of sets s1 and s2.
contains(x : object, s : set) : boolean Returns true if set s contains object x, else false.
flatten( sets : Set{Set{a}}) : Set{a} Returns the union of the elements of all sets contained in the argument sets. The signature for this function is Flatten : Set(Set(a)) ® Set(a)
setDifference(lhs, rhs : Set{a}}) : Set{a}
Returns the set difference of sets lhs and rhs. That is: rhs
– lhs. The signature of this function is SetDifference : (Set(a) x Set(a))
® Set(a)
isSubset(subset, superset : Set{a}) : boolean
Returns true if set subset is a subset of set superset, else
false
size(s : set) : integer Returns the cardinality of the set s.
sum(s : set{number}) : number Returns the sum of all of the numbers in the set s.
product(s : set{number}) : number Returns the product of the numbers in the set s.
The select(…) and collect(…) set constructors also operate on sets, but with a slightly different syntax from other functions. Set constructors are described in detail in this chapter’s section on quantification.
Literal constants may be used for comparison, as
parameters, or as functions that return their own value. Examples of literal
constants include: true, 124, “string”, and “zanzibar”.
Identifiers are names that can be resolved as references to an object.
Appropriately typed literal constants can be used as arguments to functions. Likewise, appropriately typed identifiers may be used as arguments to functions. The meaning of an identifier passed as an actual parameter to a function varies depending on the type specified by the function’s formal parameter. If the formal parameter specifies an object type then a reference to the object referred to by the identifier is passed as the function argument. This is pass-by-reference semantics. If, on the other hand, the function’s formal parameter specifies a primitive property type (int, float, boolean, string, record[…], set{…}, or sequence<…>) the identifier passed as an actual parameter is dereferenced and the value of the property referred to by the identifier is passed as the actual parameter (pass by value semantics).
None of the primitive functions specified in the Acme predicate language have side effects or change the state of the objects passed as arguments. Therefore, the parameter passing semantics can always be thought of as pass-by-value, with all of the dereferencing of identifiers done before passing the value of the object.