standard library package ControlFunctions {
doc
/*
* This package defines functions that correspond to operators in the KerML expression notation
* for which one or more operands are expressions whose evaluation is determined by another operand.
*/
private import Base::Anything;
private import ScalarValues::ScalarValue;
private import ScalarValues::Boolean;
private import ScalarFunctions::min;
private import ScalarFunctions::max;
abstract function '.' {
in feature source : Anything[0..*] nonunique {
abstract feature target : Anything[0..*] nonunique;
}
private feature chain chains source.target;
chain
}
abstract function 'if' {
in test: Boolean[1];
in expr thenValue[0..1] { return : Anything[0..*] ordered nonunique; }
in expr elseValue[0..1] { return : Anything[0..*] ordered nonunique; }
return : Anything[0..*] ordered nonunique;
}
abstract function '??' {
in firstValue: Anything[0..*] ordered nonunique;
in expr secondValue[0..1] { return : Anything[0..*] ordered nonunique; }
return : Anything[0..*] ordered nonunique;
}
function 'and' {
in firstValue: Boolean[1];
in expr secondValue[0..1] { return : Boolean[1]; }
return : Boolean[1];
}
function 'or'{
in firstValue: Boolean[1];
in expr secondValue[0..1] { return : Boolean[1]; }
return : Boolean[1];
}
function 'implies'{
in firstValue: Boolean[1];
in expr secondValue[0..1] { return : Boolean[1]; }
return : Boolean[1];
}
abstract function collect {
in collection: Anything[0..*] ordered nonunique;
in expr mapper[0..*] { in argument: Anything[1]; return : Anything[0..*] ordered nonunique; }
return : Anything[0..*] ordered nonunique;
}
abstract function select {
in collection: Anything[0..*] ordered nonunique;
in expr selector[0..*] { in argument: Anything[1]; return : Boolean[1]; }
return : Anything[0..*] ordered nonunique;
}
function selectOne {
in collection: Anything[0..*] ordered nonunique;
in expr selector1[0..*] { in argument: Anything[1]; return : Boolean[1]; }
return : Anything[0..1] = collection->select {in x; selector1(x)}#(1);
}
abstract function reject{
in collection: Anything[0..*] ordered nonunique;
in expr rejector[0..*] { in argument: Anything[1]; return : Boolean[1]; }
return : Anything[0..*] ordered nonunique;
}
abstract function reduce {
in collection: Anything[0..*] ordered nonunique;
in expr reducer[0..*] { in firstArg: Anything[1]; in secondArg: Anything[1]; return : Anything[1]; }
return : Anything[0..*] ordered nonunique;
}
abstract function forAll {
in collection: Anything[0..*] ordered nonunique;
in expr test[0..*] { in argument: Anything[1]; return : Boolean[1]; }
return : Boolean[1];
}
abstract function exists {
in collection: Anything[0..*] ordered nonunique;
in expr test[0..*] { in argument: Anything[1]; return : Boolean[1]; }
return : Boolean[1];
}
function allTrue {
in collection: Boolean[0..*];
return : Boolean[1] = collection->forAll {in x; x};
}
function anyTrue {
in collection: Boolean[0..*];
return : Boolean[1] = collection->exists {in x; x};
}
function minimize {
in collection: ScalarValue[1..*];
in expr fn[0..*] { in argument: ScalarValue[1]; return : ScalarValue[1]; }
return : ScalarValue[1] = collection->collect {in x; fn(x)}->reduce min;
}
function maximize {
in collection: ScalarValue[1..*];
in expr fn[0..*] { in argument: ScalarValue[1]; return : ScalarValue[1]; }
return : ScalarValue = collection->collect {in x; fn(x)}->reduce max;
}
}