Section 2 - Modules, Time Levels and Lists
Create a rule called buying - first in the buying category of the Content rulebase with antecedent:
and
time iteration 1\
choice ?no\
currentConsumer ?cons\
randomProducerChoice ?prodList ?no ?cons\
bestOf ?bestProd ?minPrice ?prodList ?cons\
requires ?cons ?req\
getsMoney ?cons ?money\
is ?volBought (min ?req (truncated ?money / ?minPrice))
and consequent:
bought ?cons ?volBought ?bestProd ?minPrice
This uses the backwards chaining clauses randomProducerChoice and bestOf we defined yesterday. The first line checks that this rule will only fire in the first iteration of each week, i.e. for the first in the complete queue. It then produces a random list of producers of the set length, finds the producer with the best price and then buys as much as it can afford. Now in the rule for subsequent consumers we can allow them to copy the last consumer if that is of benefit to them.
Create a rule called buying - subsequent in the buying category of the Content rulebase with antecedent:
and
choice ?no\
currentConsumer ?cons\
randomProducerChoice ?randList ?no ?cons\
last iteration (currentConsumer ?lastCons)\
last iteration (bought ?lastCons ?lastVolBought ?lastBestProd)\
appended ?prodList ?randList [?lastBestProd]\
bestOf ?bestProd ?minPrice ?prodList ?cons\
requires ?cons ?req\
getsMoney ?cons ?money\
is ?volBought (min ?req (truncated ?money / ?minPrice))
and consequent:
bought ?cons ?volBought ?bestProd ?minPrice
This is the same as the last rule except that it retrieves the producer chosen by the consumer in the last iteration with the clause section
last iteration (currentConsumer ?lastCons)\
bought ?lastCons ?lastVolBought ?lastBestProd\
and then adds this producer to the list of randomly sampled producers with the line
appended ?prodList ?randList [?lastBestProd]\
The rule can not fire in the first iteration because the clause
last iteration (currentConsumer ?lastCons)\
will fail as there was not a last iteration then.
Now restart the simulation and examine the database of the model instance at various stages to see what is happening (look especially at the clauses starting with bought).
At the moment no producers survive more than one period, because we have not written a rule to do this. Our intention is that producers survive if they have any capital left, therefore we need to do some accounting.
Go to the Final iteration rulebase and create an accounting category. First we need a rule to count up the sales, so create a rule called sales with antecedent:
and
producer ?producer\
time iteration ?now\
total ?totalSales ?volume
(and
inInterval ?iterationNo 1 ?now\
when iteration ?iterationNo (bought ?consumer ?volume ?producer ?price))
and consequent:
sold ?producer ?totalSales
The total primitive adds up all the values of ?volume that result from bindings of the sub-clause
and
inInterval ?iterationNo 1 ?now\
when iteration ?iterationNo (bought ?consumer ?volume ?producer ?price)
which in turn evaluates the clause bought ?consumer ?volume ?producer ?price at each iteration from 1 to the current (and final) iteration number, 10. For obvious reasons you can only use the when predicate to look backwards in time from the time it is evaluated. It would have been more efficient (in this case) to have asserted the bought clauses as all week (bought ...) and then we would not need the when iteration bit inside the total clause. Fetching from time stages more than two back can be slightly slower in SDML because of it may have stored these in virtual memory (i.e. on disk).
Now add a rule called profit in the same place with antecedent:
and
producer ?producer\
fixedCost ?producer ?fc\
marginalCost ?producer ?mc\
sold ?producer ?volSold\
price ?producer ?price\
is ?profit ?volSold * ?price - ?fc - ?mc * ?volSold
and consequent:
profit ?producer ?profit
This just does some simple arithmetic. We are now in a position to write the rules to calculate the new capital and assert their survival if they are solvent.
In the Initial iteration rulebase add a rule called surviving producers under the producers category with antecedent:
and
last week (and
capital ?prod ?oldCap\
profit ?prod ?profit)\
is ?newCap ?oldCap + ?profit\
notInferred
less ?newCap 0
and consequent:
all week (and
producer ?prod\
capital ?prod ?newCap)
Note the use of last week to retrieve information from the end of last week and the combination of and and all week to assert two clauses for the whole week. Finally we must write rules to get the producers to set their prices each week. This will be done by three rules lower price, keep price, and raise price.
In the content rulebase create a category called under the prices category create a rule called keep price with antecedent:
and
oldProducer ?producer\
last week (price ?producer ?price)\
last week (profit ?producer ?lastProfit)\
greater ?lastProfit 0
and consequent:
all week (price ?producer ?price)
This rule says that an existing producer will keep its price the same as last week if it made a profit. The next rule will be raise price with antecedent:
and
oldProducer ?producer\
last week (price ?producer ?lastPrice)\
last week (profit ?producer ?lastProfit)\
notInferred
greater ?lastProfit 0\
marginalCost ?producer ?mc\
less ?lastPrice ?mc\
raiseProportion ?factor\
is ?newPrice ?lastPrice * ?factor
and the consequent:
all week (price ?producer ?newPrice)
The start of the consequent is similar to the last rule but this time we check for not making a profit (notInferred greater ?lastProfit 0). The simple rule I decided on was to raise the price if the price was less than the marginal cost.
Write a rule lower price similar to the last but so that it will lower the price if the price is above the marginal cost (use the factor set by lowerProportion). To save time you can start by using the copy rule command from this pane. Then restart the simulation to see what occurs.
To see the results in a more graphical way go to the Line Chart page of the model instance. Select the select current stage command using the command button in the Selected stage: pane and enter the following clause in the middle pane and evaluate it:
and
time week ?now\
inInterval ?x 1 ?now\
when week ?x
(price ?z ?y)
It is likely that all the prices are going steadily downwards. Make a similar graph of the profits and then the amounts sold. This time you have to use evaluate final - why do you think this is? To get a key to your graphs use the command button in the graph pane.
Similarly you might want a scatter diagram of profits vs. initial profit targets. Select the Scatter Chart and evaluate the clause (using evaluate final):
and
profitTarget ?z ?x\
profit ?z ?y
Generated with CERN WebMaker