Covering the domain of a set of discrete variables can be done by
means of nested
loops(for's), however
this can result a tedious task. The variable values provide two
methods that simplifies this labor:
and
. Given a set of variables the method
sets
the variables to their initial value and the method
executes an iteration over the loop defined by the set. The order of
the iteration is from rith to left. Of course the method
is reserved for discrete type variables. Let's delineate the use of
these two methods by Program 7 which shows three
examples of typical loop frameworks.
1 /*=============================================================================
2 * File : iterateValues.cpp
3 *=============================================================================
4 *
5 *------------------------- Description ---------------------------------------
6 * This program shows how to cover all the values of a set of discrete
7 * variables (i.e. creation of loops). Three examples consisting in the
8 * more typical circumstances are shown.
9 *-----------------------------------------------------------------------------
10 */
11
12
13 #include <pl.h>
14
15 main ()
16 {
17
18 /**********************************************************************
19 Defining the variable type and symbols
20 ***********************************************************************/
21
22 plIntegerType minuteType(0,59);
23 plIntegerType hourType(0,23);
24
25 plSymbol minute("minute",minuteType);
26 plSymbol hour("hour",hourType);
27
28 plRealType temperature(-20,40,100);
29 plRealType humidity(0.0,1.0,25);
30 plRealType speed(0,70,20);
31
32 plSymbol hi("Hi",temperature);
33 plSymbol lo("Lo",temperature);
34 plSymbol wind_speed("wind_speed",speed);
35 plSymbol wind_humidity("wind_humidity",humidity);
36
37 /**********************************************************************
38 First example: A loop for all the variables in the plValues
39 with the order of iteration given by the order used at the creation
40 of the plValues.
41 ***********************************************************************/
42
43 cout<<"Fist example output : \n";
44
45 plValues time(hour^minute); // "time" is {hour, minute}
46
47 time.reset(); // Reset all values in "time"
48 do
49 cout<<time<<endl;
50 while(time.next()); // Set the next value for {hour, time}
51 cout<<"\n\n";
52
53 /*** The result is not the same for "time2": Note that minute and hour
54 are inversed w.r.t. to "time" ***/
55 plValues time2(minute^hour); // "time2" contains : minute and hour
56
57 time2.reset(); // Reset all values in "time"
58 do
59 cout<<time2<<endl;
60 while(time2.next()); // Set the next value for {time, hour}
61 cout<<"\n\n";
62
63 /**********************************************************************
64 Second example: Shows a loop that iterates one explicit variable at
65 a time
66 ***********************************************************************/
67
68 cout<<"Second example output : \n";
69 time2.reset(hour); // Reset the value of {hour}
70 do {
71 time2.reset(minute); // Resets the value of {minute}
72 do
73 cout<<time2<<endl;
74 while (time2.next(minute));// Set the next value for {minute}
75 } while(time2.next(hour)); // Set the next value for {hour}
76
77
78 /**********************************************************************
79 Third example: A loop for a subset of variables of the plValues
80 with a particular order of iteration. Note that this example is
81 presented with discrete plReals to show that loop are also possible
82 for this type of variables.
83 ***********************************************************************/
84
85 cout<<"Third example output : \n";
86 plValues forecast(hi^lo^wind_speed^wind_humidity);
87
88 forecast[hi] = 61.5;
89 forecast[lo] = 51.0;
90
91 forecast.reset(wind_humidity^wind_speed); // Reset the values of
92 // {wind_humidity, wind_speed}
93 do
94 cout<<forecast<<endl;
95 while(forecast.next(wind_humidity^wind_speed)); // Set the next value for
96 // {wind_humidity, wind_speed}
97
98 }
Lines 37 to 62 shows a first example for two loops with the same set
of variables but different order of iteration. The fist loop is over
hour and minute. Line 45 creates a variable values
with these two symbols and line 47 resets its values. In fact if no
argument is passed to
then all the variables are set to
their respective initial values. Lines 48 to 50 correspond to the loop
over hour and minute. If minute is not at its
maximum extremum the command time.next() increments its value
by one, otherwise it increments hour and resets minute
to its initial value. time.next() returns
unless all
variables are at their maximum extrema. Otherwise stated lines 47 to 50
are equivalents to the following code in C:
for(time[hour]=0; time[hour]<=23; time[hour]=time[hour]+1)
for(time[minute]=0;time[minute]<=59;time[minute]=time[minute]+1)
cout<<time<<endl;
the output of lines 47 to 50 is:
{hour=0 minute=0}
{hour=0 minute=1}
{hour=0 minute=2}
{hour=0 minute=3}
.
.
.
{hour=12 minute=0}
{hour=12 minute=1}
{hour=12 minute=2}
{hour=12 minute=3}
.
.
.
{hour=23 minute=56}
{hour=23 minute=57}
{hour=23 minute=58}
{hour=23 minute=59}
The second loop, lines 53 to 61, is a loop over minute and
hour. Note that time2 in line 55 is created by inversing
hour and minute with respect to
time. Consequently lines 58 to 60 are equivalent to the
following code in C:
for(time[minute]=0;time[minute]<=59;time[minute]=time[minute]+1)
for(time[hour]=0; time[hour]<=23; time[hour]=time[hour]+1)
cout<<time<<endl;
the output of lines 58 to 60 is:
Second example output :
{minute=0 hour=0}
{minute=0 hour=1}
{minute=0 hour=2}
{minute=0 hour=3}
.
.
.
{minute=30 hour=0}
{minute=30 hour=1}
{minute=30 hour=2}
{minute=30 hour=3}
.
.
.
{minute=59 hour=21}
{minute=59 hour=22}
{minute=59 hour=23}
Observe that not only the variables of time2 are printed differently
from that of time but that hour is iterated before
minute.
The second example is presented in lines 63 to 77. The result of lines 69 to 75 is equivalent to that of lines 47 to 50. The difference lies in iterating a single variable at a time.
Finally, the third example illustrates how to reset and iterate a
subset of variables within a specific order. Line 91 resets the values
of wind_humidity and wind_speed. The command
forecast.next(wind_humidity^wind_speed) in line 95 iterates
over wind_humidity and wind_speed. The output of lines
85 to 95 shows as follows:
Third example output :
{Hi=61.5 Lo=51 wind_speed=1.75 wind_humidity=0.02}
{Hi=61.5 Lo=51 wind_speed=5.25 wind_humidity=0.02}
{Hi=61.5 Lo=51 wind_speed=8.75 wind_humidity=0.02}
{Hi=61.5 Lo=51 wind_speed=12.25 wind_humidity=0.02}
.
.
.
{Hi=61.5 Lo=51 wind_speed=57.75 wind_humidity=0.98}
{Hi=61.5 Lo=51 wind_speed=61.25 wind_humidity=0.98}
{Hi=61.5 Lo=51 wind_speed=64.75 wind_humidity=0.98}
{Hi=61.5 Lo=51 wind_speed=68.25 wind_humidity=0.98}
The loop affects exclusively the variables passed as argument to
. Remember that a discrete real interval
is
composed by the union
. Thus, the
method
initialize the discrete real type variables to the mid
point of
equal to
. Similarly,
iterates by adding
and reseting to
the first mid point.