home *** CD-ROM | disk | FTP | other *** search
-
-
- Listing 1
-
- A demonstration program written in OPS83 to solve extremely
- simple DC circuits using Ohm's Law.
-
-
- module ohms(start_ohms)
- {
- use shell;
- use utils;
-
- --First we have to model the circuit.
-
- --Devices look like this:
-
- type device = element
- (type : symbol; -- resistor, voltsource
- tag : symbol; -- tag identifies each unique device
- i : real; --current through device
- istat : symbol; --status of i, solved or unknown
- val : real; -- value of device in ohms or volts
- valstat : symbol; --is value known?
- );
-
- --All devices are connected to junctions. Two devices connected
- --to the same junction are connected to each other.
- type connect = element
- (dev : symbol;
- trm : integer;
- junct : symbol;);
-
- --All junctions have a voltage. Implicitly, this means that
- --all terminals at a junction are at the same potential.
-
- type junct = element
- (tag : symbol;
- volts : real;
- vstat : symbol);
-
-
- -- An equivalent resistor is one which is substituted for
- -- a resistor using one of the combining forms. The values
- -- and connections of the replaced resistors are stored in
- -- the wme for future use.
-
- type equiv_r = element
- (type : symbol;
- tag : symbol;
- r1 : symbol; -- connections for r1
- r1t1 : integer; -- terminals
- r1t2 : integer;
- r1j1 : symbol; -- junctions
- r1j2 : symbol;
- r2 : symbol; -- connections for r2
- r2t1 : integer;
- r2t2 : integer;
- r2j1 : symbol;
- r2j2 : symbol;
- );
-
- --The start procedure. In this procedure, the circuit is modeled,
- --and whatever values are known are set.
- procedure start_ohms()
- {
- make (device type=voltsource; tag=v1;val=12.0;i=12.0;istat=unknown);
- make (device type=resistor;tag=r1;val=10.0;valstat=known;i=12.0;istat=unknown);
- make (device type=resistor;tag=r2;val=4.0;i=12.0;valstat=known;istat=unknown);
- make (device type=resistor;tag=r3;val=2.0;valstat=known;i=12.0;istat=unknown);
- make (device type=resistor;tag=r4;val=4.0;valstat=known;istat=unknown);
- make (device type=resistor;tag=r5;val=8.0;valstat=known;i=12.0;istat=unknown);
- make (device type=resistor;tag=r6;val=8.0;valstat=known;istat=unknown);
- make (connect dev=v1;trm=1;junct=j1);
- make (connect dev=v1;trm=2;junct=j4);
- make (connect dev=r1;trm=1;junct=j1);
- make (connect dev=r1;trm=2;junct=j2);
- make (connect dev=r2;trm=1;junct=j2);
- make (connect dev=r3;trm=1;junct=j2);
- make (connect dev=r2;trm=2;junct=j4);
- make (connect dev=r3;trm=2;junct=j3);
- make (connect dev=r4;trm=1;junct=j3);
- make (connect dev=r5;trm=1;junct=j3);
- make (connect dev=r6;trm=1;junct=j3);
- make (connect dev=r4;trm=2;junct=j4);
- make (connect dev=r5;trm=2;junct=j4);
- make (connect dev=r6;trm=2;junct=j4);
- make (junct volts=12.0;vstat=known;tag=j1);
- make (junct vstat=unknown;tag=j2);
- make (junct vstat=unknown;tag=j3);
- make (junct volts=0.0;vstat=known;tag=j4);
- call run(100); -- run the production system
- };
-
-
- --Some simple rules derived from Ohms Law
-
- --If you know the voltage across a device, and the resistance of the
- --device, than you know the current through the device
- rule compute_current
- { &1 (device type=resistor;istat=unknown;valstat=known);
- &2 (connect dev=&1.tag;trm=1); -- get the junctions involved
- &3 (junct tag=&2.junct;vstat=known);
- &4 (connect dev=&1.tag;trm=2);
- &5 (junct tag=&4.junct;vstat=known);
- -->
- -- I = V/R
- -- Establish convention, current flows from t1 to t2 in
- -- each device. A negative sign indicates the inverse.
- modify &1 (i= (&3.volts - &5.volts)/&1.val;istat=known)
- };
-
- --If you know the resistance of a device and the current
- --through that device, then you can compute the voltage drop
- --across the device.
-
- rule compute_voltage
- { &1 (device type=resistor;istat=known;valstat=known);
- &2 (connect dev=&1.tag); -- get the junctions involved
- &3 (junct tag=&2.junct;vstat=unknown);
- &4 (connect dev=&1.tag;junct<>&2.junct);
- &5 (junct tag=&4.junct;vstat=known); -- one is unknown
- -->
- -- (V1 - V2) = IR
- modify &3 (volts = &1.val * &1.i + &5.volts; vstat=known);
- };
-
- --If you know the voltage across a device, and the current
- --through the device, then you can compute the resistance.
- rule compute_resistance
- { &1 (device type=resistor;istat=known;valstat=unknown);
- &2 (connect dev=&1.tag;trm=1); -- get the junctions involved
- &3 (junct tag=&2.junct;vstat=known);
- &4 (connect dev=&1.tag;trm=2);
- &5 (junct tag=&4.junct;vstat=known);
- -->
- -- R = V/I
- modify &1 (val = (&3.volts - &5.volts)/&1.i;valstat=known);
- };
-
- --Resistor manipulations
-
- -- Two resistors in series can be replaced by one resistor with
- -- value R1 + R2
-
- rule replace_series
- { &1 (device type=resistor;istat=unknown;valstat=known); --find device
- &2 (connect dev=&1.tag;trm=2);
- &3 (device type=resistor;istat=unknown;valstat=known;tag<>&1.tag);
- &4 (connect dev=&3.tag;junct=&2.junct); --find common junction
- --no other device connected to junction (resistors are in series)
- ~(connect junct=&2.junct;(@.dev <> &3.tag /\ @.dev <> &1.tag));
- -- find other connections to these devices
- &5 (connect dev=&1.tag;junct<>&2.junct);
- &6 (connect dev=&3.tag;junct<>&4.junct);
- -->
- local &equiv : symbol;
- &equiv = gensym(equiv);
- make(equiv_r type=series;tag=≡r1=&1.tag;
- r1t1=&5.trm;r1t2=&4.trm;
- r1j1=&5.junct;r1j2=&4.junct;
- r2t1=&6.trm;r2t2=&4.trm;
- r2j1=&6.junct;r2j2=&4.junct;
- r2=&3.tag);
- make(device type=resistor;tag=≡istat=unknown;
- val = &1.val + &3.val;valstat=known);
- --substitute new device into circuit
- modify &5 (dev=≡trm=1);
- modify &6 (dev=≡trm=2);
- remove &2; -- disconnect replaced resistors
- remove &4;
- };
-
-
- -- Two resistors in parallel can be replaced by one resistor with
- -- value (R1 * R2)/(R1 + R2)
-
- rule replace_parallel
- { &1 (device type=resistor;istat=unknown;valstat=known); --find device
- --find both connections to that device.
- &2 (connect dev=&1.tag;trm=1);
- &3 (connect dev=&1.tag;trm=2);
- --now, find another device connected to both junctions
- &4 (device type=resistor;istat=unknown;valstat=known;tag<>&1.tag);
- &5 (connect dev=&4.tag;junct=&2.junct); --find common junction
- &6 (connect dev=&4.tag;junct=&3.junct); --find common junction
- -->
- local &equiv : symbol;
- &equiv = gensym(equiv);
- make(equiv_r type=parallel;tag=≡r1=&1.tag;
- r1t1=&2.trm;r1t2=&3.trm;
- r1j1=&2.junct;r1j2=&3.junct;
- r2t1=&5.trm;r2t2=&6.trm;
- r2j1=&5.junct;r2j2=&6.junct;
- r2=&4.tag);
- make(device type=resistor;tag=≡istat=unknown;
- val = (&1.val * &4.val)/(&1.val + &4.val);valstat=known);
- --substitute new device into circuit
- modify &5 (dev=≡trm=1);
- modify &6 (dev=≡trm=2);
- remove &2;
- remove &3;
- };
-
-
- --After an equivalent resistor has been solved, it can be replaced
- --by its constituent parts
-
- rule replace_equiv --replace equivalent resistor
- { &1 (equiv_r ); -- find an equivalent resistor
- &2 (device tag=&1.tag;istat=known;valstat=known); --which is solved
- &3 (connect dev=&2.tag);
- &4 (junct tag=&3.junct;vstat=known);
- &5 (connect dev=&2.tag;junct<>&3.junct);
- &6 (device tag=&1.r1);
- &7 (device tag=&1.r2);
- -->
- if (&1.type = series)
- {
- --current in a series circuit is current through equivalent resistor
- modify &6 (istat=&2.istat;i=&2.i);
- modify &7 (istat=&2.istat;i=&2.i)}
- else {
- --current in a parallel circuit is I1 = Iequiv*R2/(R1+R2)
- modify &6 (istat=&2.istat;i=&2.i * &7.val/(&7.val + &6.val));
- modify &7 (istat=&2.istat;i=&2.i * &6.val/(&7.val + &6.val))};
- remove &2; -- remove equivalent resistor
- --reconnect original resistors
- make (connect dev=&1.r1;junct=&1.r1j1;trm=&1.r1t1);
- make (connect dev=&1.r1;junct=&1.r1j2;trm=&1.r1t2);
- make (connect dev=&1.r2;junct=&1.r2j1;trm=&1.r2t1);
- make (connect dev=&1.r2;junct=&1.r2j2;trm=&1.r2t2);
- remove &5; -- remove connections for equiv resistor
- remove &3;
- };
-
-
- }; -- end of module
-