Broadly, there are two types of stars in the SR domain: strict and non-strict. If any input to a strict star is unknown, then all of its outputs are unknown. A two-input adder, for example, behaves like this--it cannot say anything about its output until the values of both inputs are known. A non-strict star, by contrast, can produce some outputs before all of its inputs are known. A two-input multiplexer is an example: when the selection input is known, it can ignore the unselected input.
Non-strict stars are the key to avoiding deadlocked situations when there are cyclic connections in the system. If all the stars in a cycle are strict, they each need all of their inputs before producing an output--all will be left waiting. The deadlock can be broken by introducing a non-strict star into the cycle that can produce an output without having all inputs from other stars in the cycle
A number of methods set attributes of SR stars. These should be called in the setup()
method of a star as appropriate. By default, none of these attributes is assumed to hold.
SRStar::reactive()
Indicate the star is reactive--it needs at least one present input to produce a present output.
Star::noInternalState()
Indicate the star has no internal state--its behavior in an instant is a function only of the inputs in that instant, and not on history.
By default, a star in the SR domain is strict. Here is (abbreviated) ptlang
source for a two-input adder:
defstar {
name { Add }
domain { SR }
input {
name { input1 }
type { int }
}
input {
name { input2 }
type { int }
}
output {
name { output }
type { int }
}
setup {
reactive();
noInternalState();
}
go {
if ( input1.present() && input2.present() ) {
output.emit() <<
int(input1.get()) + int(input2.get());
} else {
Error::abortRun(*this,
"One input present, the other absent");
}
}
}
Non-strict stars inherit from the SRNonStrictStar
class. Here is abbreviated source for a non-strict two-input multiplexer:
defstar {
name { Mux }
domain { SR }
derivedFrom { SRNonStrictStar }
input {
name { trueInput }
type { int }
}
input {
name { falseInput }
type { int }
}
input {
name { select }
type { int }
}
output {
name { output }
type { int }
}
setup {
noInternalState();
reactive();
}
go {
if ( !output.known() && select.known() ) {
if ( select.present() ) {
if ( int(select.get()) ) {
// Select is true--
// copy the true input if it's known
if ( trueInput.known() ) {
if ( trueInput.present() ) {
output.emit() <<
int(trueInput.get());
} else {
// true input is absent:
// make the output absent
output.makeAbsent();
}
}
} else {
// Select is false--
//copy the false input if it's known
if ( falseInput.known() ) {
if ( falseInput.present() ) {
output.emit() <<
int(trueInput.get());
} else {
// false input is absent:
// make the output absent
output.makeAbsent();
}
}
}
} else {
// Select is absent:
// make the output absent
output.makeAbsent();
}
}
}
}
Copyright © 1990-1997, University of California. All rights
reserved.