#11. Example 2. Planning problem solving for electric circuits. Consider a task known from the UTOPIST language, computation of values for electric circuits made up of resistors based on Ohm and Kirchhof laws. A circuit is specified and some of values (resistance, current, or voltage) are given. One more such value (or several values) is to be found. To do this one has to plan a sequence of steps in which some of the unknown values will be computed from certain formulas in a certain order.

Consider a circuit of three resistors shown in pic.8. Let their resistances be given, the resistance of the whole circuit is to be found; the formulas for the resistance of serial and parallel combinations of resistors are supposed to be unknown. The problem can be solved if the value of voltage or current is specified for at least one of the resistors (in this example, the current I through R2). Then, by a sequence of steps one can obtain the values of voltage and current for the whole circuit, and thence the resistance (obviously, the previously introduced value of the current through R2 can be eliminated from the final expression, but without it the system would be unable to find the solution). The solution is produced as a formula rather than a numerical value; denoting the values of resistance of R1, R2, and R3 by the same symbols as the resistors themselves one gets the solution


((I+I*R2/R3)*R1+I*R2)/(I+I*R2/R3)

Let us consider the the modules used as well as the representation of the circuit in detail. The phrase "may have an attribute so-and-so" means that the attribute with the given name, not mentioned directly in the module, can be used by procedures in the module if it is set "from outside".

1. Variable (speaking more precisely, a formula consisting of a single variable). Has a "name" attribute and a printing procedure to print out the name.

2. Binary formula (four of such modules, viz., for addition, subtraction, multiplication, and division). Has attributes for "operation symbol" and "operation priority". May have attributes for "operand1" and "operand2". Has a printing procedure (the same for all four modules) containing calls to similar procedures for the operands. This procedure receives a parameter, the priority of the outer operation, in order to decide whether to print parentheses.

3. Arithmetical relationship (two such modules, one for x+y=z and one for x*y=z). Has attributes named "operand1" (x), "operand2" (y), and "result" (z). To each of the three nodes a set of computational procedures (in this case, a one-element set) is attached. The module for the "sum" relationship is shown in pic.9.

4. Resistor. Has attributes for "voltage", "current" and "resistance". In this module a "product" relationship is included, i.e., a node to which the module for this relationship is ascribed. From this node arcs named "operand1", "operand2", and "result" lead to the nodes representing, respectively, the "current", "resistance", and "voltage" attributes of the resistor. This is how the Ohm's law is represented.

5. Resistors connected in parallel. This module is included in the class "resistor", i.e., the "resistor" module is ascribed to the main node. It has also "resistor1" and "resistor2" attributes. For the main node as well as for the two nodes corresponding to these attributes there are explicit attibutes named "voltage" and "current". It is seen from pic.10, how to show that the three voltage values are the same and the current values are connected by the "sum" relationship (the picture does not show arcs introduced from ascribed modules, only the module names are shown).

The module for serially connected resistors has a similar structure.

The net representing the task to be solved is shown in pic.11 (without the ascribed modules).

By ascribing all the indicated modules each of the values will get a "methods of computation" attribute referring to a set of procedures. These sets are no longer one-element sets because information from many sources has been brought together. E.g., for the value of the current through the whole circuit four methods of computation will be given: (1) from the voltage across the whole circuit and its resistance, (2) from the voltage across R1 and its resistance (since there is information that the current through R1 and that through the whole circuit are one same thing), (3) from the voltage across the pair R2, R3 and its resistance, (4) as the sum of the currents through R2 and R3.

Next a connection is established between the concepts of "value" and "methods of computation", as shown in #6. Consequently, a request for an absent "value" attribute results in successive calling all computation procedures until one of them succeeds. The procedure shown in pic.9 as "x+y" consists of the following steps. Find the "value" attribute of the x node, fail if no attribute; the same for the y node; find the "value" attribute of the node under consideration, i.e., z (this attribute could have been set in the course of preceding actions) and, if found, return it as the result, otherwise do the following: fetch a "binary formula" module for addition, attach to it the previously found values of x and y as operands, and return the main node of the module as the result after having attached it as the value to the considered node.

The requests for "value" attributes of the x and y nodes in this procedure may result in calling similar procedures for these nodes, in course of which some nodes that did not have a "value" attribute may receive one. It can happen that one of those nodes will be the considered node, therefore, when the values of x and y have been found, it is necessary to test the existence of this attribute for the considered node, though it did not exist before start of the procedure (or else there would be no point in calling it). If we don't test it, an error can occur because of the fact that only one "value" is attached to a quantity rather than a set of values. The "values" actually being formulas, it can happen that the same place will be occupied by two different (albeit equivalent) formulas. In this case the two formulas will be mechanically merged, it will spread to their respective operands, etc., so very different quantities will be merged.

On the other hand, looking for a value of a node inside a procedure called exactly for finding this value will not lead to an infinite recursion because the system detects such attempts and returns a failure. An interesting feature of the "resistor" module as well as of subsequent modules (see pic.10) is that the computation of attributes of the main node is affected by ascribing a module for an arithmetical relationship to a node inaccessible from that main node. This is due to the already mentioned flaw in the implementation causing all the ascribed modules to be fetched simultaneously with the main module. If fetching an ascribed module were postponed to the first access to the node concerned, the "resistor" module as well as others would not work in the present form exactly because of inaccessibility of the arithmetical relationship node. This is probably what should be; for a node representing a quantity the set of relationships involving this quantity should be given as an attribute.

In general, the process of solving the task after the circuit has been assembled looks as follows: for the node marked at pic.11 as the desired quantity the "value" is sought for, and if the search is successful (which happens to be the case) for the value obtained (a formula or a variable) its print function is called.

As it was noted before, solving problems requiring complex search is not a typical use of this programming system, but one cannot completely eliminate the need of solving small subtasks of this type within a generally deterministic plan. Solving this paricular example did not take excessive computer resources; on a ES-1045 computer it took about 1 second cpu time and less than 50K storage.