First, a hierarchy of entity types is set up. The system dynamics
models shown earlier contain only three types of participant: variables,
stocks and flows. Here, stocks and flows are a special type of
variable with a predetermined meaning. That is, a flow into a
stock
corresponds to the equation
and a
flow
out of a stock
denotes
. Hence,
stocks and flows are defined as subclasses of the participant class
variable:
(defEntity variable) (defEntity stock :subclass-of (variable)) (defEntity flow :subclass-of (variable))
The sample properties defined in section 3.2.3, which describe the condition under which a variable is endogenous or exogenous, are employed in this knowledge base:
(defproperty endogenous-1 :source-participants ((?v :type variable)) :structural-conditions ((== ?v *)) :property (endogenous ?v)) (defproperty endogenous-2 :source-participants ((?v :type variable)) :structural-conditions ((d/dt ?v *)) :property (endogenous ?v)) (defproperty exogenous :source-participants ((?v :type variable)) :structural-conditions ((not (endogenous ?v))) :property (exogenous ?v))
The next three model fragments contain the rules of the stock-flow diagrams employed by systems dynamics models. They respectively describe that:
![]() |
![]() |
![]() ![]() |
(defModelFragment inflow :source-participants ((?stock :type stock) (?flow :type flow)) :structural-conditions ((flow ?flow source ?stock)) :postconditions ((d/dt ?stock (C-add ?flow))))
(defModelFragment outflow :source-participants ((?stock :type stock) (?flow :type flow)) :structural-conditions ((flow ?flow ?stock sink)) :postconditions ((d/dt ?stock (C-sub ?flow))))
(defModelFragment inflow :source-participants ((?stock1 :type stock) (?stock2 :type stock) (?flow :type flow)) :structural-conditions ((flow ?flow ?stock1 ?stock2)) :postconditions ((d/dt ?stock1 (C-sub ?flow)) (d/dt ?stock2 (C-add ?flow))))
Once the above declarations are in place, the knowledge base of model fragments can be defined. The first model fragment describes the population growth phenomenon. Note that all of the aforementioned growth, predation and competition models contain a stock representing population size and two flows, one flow of births into the stock and another flow of deaths out of the stock. This common feature of models on population dynamics is contained in a single model fragment.
(defModelFragment population-growth :source-participants ((?population :type population)) :assumptions ((relevant growth ?population)) :target-participants ((?size :type stock :name size) (?birth-flow :type flow :name births) (?death-flow :type flow :name deaths)) :postconditions ((flow ?birth-flow source ?size) (flow ?death-flow ?size sink) (size-of ?size ?population) (births-of ?birth-flow ?population) (deaths-of ?death-flow ?population)) :purpose-required ((endogenous ?birth-flow) (endogenous ?death-flow)))
The variables ?birth-flow and ?death-flow become endogenous if the model contains an equation describing birth flow and death flow. These equations differ between population growth models. Two types of population growth model are the exponential growth model [26], which is shown in Figure 8(a), and the logistic growth model [43], which is shown in Figure 8(b). The following two model fragments formally describe these component models:
(defModelFragment exponential-population-growth :source-participants ((?population :type population) (?size :type variable) (?birth-flow :type variable) (?death-flow :type variable)) :structural-conditions ((size-of ?size ?population) (births-of ?birth-flow ?population) (deaths-of ?death-flow ?population)) :assumptions ((model ?size exponential)) :target-participants ((?birth-rate :type variable :name birth-rate) (?death-rate :type variable :name death-rate)) :postconditions ((== ?birth-flow (* ?birth-rate ?size)) (== ?death-flow (* ?death-rate ?size))))
(defModelFragment logistic-population-growth :source-participants ((?population :type population) (?size :type variable) (?birth-flow :type variable) (?death-flow :type variable)) :structural-conditions ((size-of ?size ?population) (births-of ?birth-flow ?population) (deaths-of ?death-flow ?population)) :assumptions ((model ?size logistic)) :target-participants ((?birth-rate :type variable :name birth-rate) (?death-rate :type variable :name death-rate) (?density :type variable :name total-population) (?capacity :type variable :name capacity)) :postconditions ((== ?birth-flow (* ?birth-rate ?size)) (== ?death-flow (* ?death-rate ?size ?density)) (== ?density (C-add (/ ?size ?capacity))) (density-of ?density ?population) (capacity-of ?capacity ?population)))
There is one twist in compositional modelling of population growth. Sometimes, the actual growth model is implicitly contained within another type of model. In such cases, the growth phenomenon and the corresponding differential equations are still relevant, but none of the dedicated growth models can be employed. For example, as will be shown later, the Lotka-Volterra predation model comes with its own equations describing growth.
The model fragment other-growth allows for an empty growth model, named other, to be selected. However, due to the purpose-required property that any instance of ?p-change must be endogenous, this empty model can only be selected if a growth model is implicitly included elsewhere.
(defModelFragment other-growth :source-participants ((?population :type population) (?size :type variable) (?birth-flow :type variable) (?death-flow :type variable)) :structural-conditions ((size-of ?size ?population) (births-of ?birth-flow ?population) (deaths-of ?death-flow ?population)) :assumptions ((model ?population other)))
In addition to population growth, two other phenomena are included in the knowledge base: predation and competition. Predation and competition relations between species are represented by predicates over the populations: e.g. (predation foxes rabbits) and (competition sheep cows). However the existence of a phenomenon does not necessarily mean that it must be contained within the model. It would make little sense to model predation and competition without modelling the size of the populations, because models of these phenomena relate population sizes to one another. Therefore, the incorporation of the predation phenomenon is made dependent upon the existence of variables representing population size. Also, human expert modellers may prefer to leave a phenomenon out of the resulting model. To keep this choice open, the following two model fragments construct a participant representing the phenomena of predation and competition, and make it dependent upon a relevance assumption:
(defModelFragment predation-phenomenon :source-participants ((?predator :type population) (?prey :type population) (?predator-size :type variable) (?prey-size :type variable)) :structural-conditions ((predation ?predator ?prey) (size-of ?predator-size ?predator) (size-of ?prey-size ?prey)) :assumptions ((relevant predation ?predator ?prey)) :target-participant ((?predation-phenomenon :type phenomenon :name predation-phenomenon)) :postconditions ((predation-phenomenon ?predation-phenomenon ?predator ?prey)) :purpose-required ((has-model ?predation-phenomenon)))
(defModelFragment competition-phenomenon :source-participants ((?population1 :type population) (?population2 :type population) (?size1 :type variable) (?size2 :type variable)) :structural-conditions ((competition ?population1 ?population2) (size-of ?size1 ?population1) (size-of ?size2 ?population2)) :assumptions ((relevant competition ?population1 ?population2)) :target-participant ((?competition-phenomenon :type phenomenon :name competition-phenomenon)) :postconditions ((competition-phenomenon ?competition-phenomenon ?population1 ?population2)) :purpose-required ((has-model ?competition-phenomenon)))
Both model fragments have a purpose-required property of the form (has-model ?phen). This property expresses the condition that a model must exist with respect to a phenomenon:
(defproperty has-model :source-participants ((?p :type phenomenon)) :structural-conditions ((is-model-of ?p *)) :property (has-model ?p))
The next two model fragments implement such models (thereby satisfying the above has-model purpose-required property) for the predation phenomenon between two populations. They describe two well-known predation models: the Lotka-Volterra model [25,44], which is shown in Figure 9(a), and the Holling model [16], which is shown graphically in Figure 9(b).
(defModelFragment Lotka-Volterra :source-participants ((?predation-phenomenon :type phenomenon) (?predator :type population) (?predator-size :type stock) (?predator-birth-flow :type flow) (?predator-death-flow :type flow) (?prey :type population) (?prey-size :type stock) (?prey-birth-flow :type flow) (?prey-death-flow :type flow)) :structural-conditions ((predation-phenomenon ?predation-phenomenon ?predator ?prey) (size-of ?predator-size ?predator) (births-of ?predator-birth-flow ?predator) (deaths-of ?predator-death-flow ?predator) (size-of ?prey-size ?prey) (births-of ?prey-birth-flow ?prey) (deaths-of ?prey-death-flow ?prey)) :assumptions ((model ?predation-phenomenon lotka-volterra)) :target-participants ((?prey-birth-rate :type variable :name birth-rate) (?predator-factor :type variable :name predator-factor) (?prey-factor :type variable :name prey-factor) (?predator-death-rate :type variable :name death-rate)) :postconditions ((== ?prey-birth-flow (* ?prey-birth-rate ?prey-size)) (== ?predator-birth-flow (* ?predator-factor ?prey-size ?predator-size)) (== ?prey-death-flow (* ?prey-factor ?prey-size ?predator-size)) (== ?predator-death-flow (* ?predator-death-rate ?predator-size)) (is-model-of lotka-volterra ?predation-phenomenon)))
As mentioned earlier, the Lotka-Volterra model introduces its own growth model for the prey and predator populations by assigning specific equations to the variables, which describe changes in the sizes of the predator and prey populations, ?pred-change and ?prey-change respectively. Thus, it satisfies the purpose-required property in the application of the population-growth model fragment for the ?prey and ?pred populations.
(defModelFragment Holling :source-participants ((?predation-phenomenon :type phenomenon) (?predator :type population) (?predator-size :type stock) (?capacity :type variable) (?prey :type population) (?prey-size :type stock)) :structural-conditions ((predation-phenomenon ?predation-phenomenon ?predator ?prey) (size-of ?predator-size ?predator) (size-of ?prey-size ?prey) (capacity-of ?capacity ?predator)) :assumptions ((model ?predation-phenomenon holling)) :target-participants ((?search-rate :type variable :name search-rate) (?handling-time :type variable :name handling-time) (?prey-requirement :type variable :name prey-requirement) (?predation :type flow :name predation)) :postconditions ((flow ?predation ?prey-size sink) (== ?predation (/ (* ?search-rate ?prey-size ?predator-size) (+ 1 (* ?search-rate ?prey-size ?handling-time)))) (== ?capacity (C-add (* ?prey-requirement ?prey))) (is-model-of holling ?predation-phenomenon)))
The Holling model employs a variable denoting the capacity of a population. Such a variable may be introduced by a logistic growth model. In practice, logistic growth models and Holling predation models are often used in conjunction. The compositional modeller need not be aware of such combinations of models, however. All it needs to know is the prerequisites of the individual component models contained within each model fragment.
The final model fragment in the knowledge base implements a model of competition between two species. It formally describes the competition model type depicted in Figure 10. As this model fragment contains the only population competition model in the knowledge base, it does not contain a model assumption to represent the model.
(defModelFragment competition :source-participants ((?competition-phenomenon :type phenomenon) (?population-1 :type population) (?size-1 :type stock) (?density-1 :type variable) (?capacity-1 :type variable) (?population-2 :type population) (?size-2 :type stock) (?density-2 :type variable) (?capacity-2 :type variable)) :structural-conditions ((competition-phenomenon ?competition-phenomenon ?population-1 ?population-2) (density-of ?density-1 ?size-1) (capacity-of ?capacity-1 ?size-1) (density-of ?density-2 ?size-2) (capacity-of ?capacity-2 ?size-2)) :assumptions ((relevant competition ?population-1 ?population-2)) :target-participants ((?weight-12 :type variable :name weight) (?weight-21 :type variable :name weight)) :postconditions ((== ?density-1 (C-add (/ (* ?weight-12 ?size-2) ?capacity-1))) (== ?density-2 (C-add (/ (* ?weight-21 ?size-1) ?capacity-2)))))