home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
aijournl
/
aifirst.arc
/
OPS83.LTG
< prev
next >
Wrap
Text File
|
1986-10-30
|
8KB
|
239 lines
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