This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
vsc e5f4633c39 This commit was generated by cvs2svn to compensate for changes in r4,
which included commits to RCS files with non-trunk default branches.


git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@5 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
2001-04-09 19:54:03 +00:00

421 lines
11 KiB
Plaintext

/*
**********************************************************************
*
* CLP(R) Version 2.0 (Example Programs Release)
* (C) Copyright, March 1986, Monash University
*
**********************************************************************
*/
%
% Package for sinusoidal steady state analysis of RLC circuits.
% The two goals ?- go1 and ?- go2 analyse two
% circuits of moderate complexity.
%
circuit_solve(W, L, G, Selection) :-
get_node_vars(L, NV),
solve(W, L, NV, Handles, G),
format_print(Handles, Selection).
get_node_vars([[Comp, Num, X, Ns]|Ls], NV) :-
get_node_vars(Ls, NV1),
insert_list(Ns, NV1, NV).
get_node_vars([], []).
insert_list([N|Ns], NV1, NV3) :-
insert_list(Ns, NV1, NV2),
insert(N, NV2, NV3).
insert_list([], NV, NV).
insert(N, [[N, V, I]|NV1], [[N, V, I]|NV1]) :- !.
insert(N, [[N1, V, I]|NV1], [[N1, V, I]|NV2]) :-
insert(N, NV1, NV2).
insert(N, [], [[N, V, c(0,0)]]).
eps(0.001).
solve(W, [X|Xs], NV, [H|Hs], G) :-
addcomp(W, X, NV, NV1,H),
solve(W, Xs, NV1, Hs, G).
solve(W, [], NV, [], G) :-
!,
zero_currents(NV),
ground_nodes(NV, G).
zero_currents([[N, V, c(X,Y)]|Ls]) :-
zero(X),
zero(Y),
zero_currents(Ls).
zero_currents([]).
zero(0).
zero(X) :-
ground(X),
%printf("Is it ground: % ?\n", [X]),
eps(EPS),
X > -EPS,
X < EPS.
/* There is some redundancy setting all node current sums to zero - We only
need to some of them to zero. Setting all of them to zero can cause some
problems because of numerical instability. */
ground_nodes(Vs,[N|Ns]) :-
ground_node(Vs, N),
ground_nodes(Vs, Ns).
ground_nodes(Vs, []).
ground_node([[N, c(0,0), I]|Vs], N) :- !.
ground_node([[N1, V, I]|Vs], N) :- ground_node(Vs, N).
ground_node([], N) :- printf("Error could be: node %doesn't exist\n", [N]).
% ***** CLAUSES TO DEFINE COMPONENT CHARACTERISTICS *****
addcomp(W, [Comp2, Num, X, [N1, N2]], NV, NV2, [Comp2, Num, X, [N1, V1, I1], [N2, V2, I2]]):-
c_neg(I1, I2),
iv_reln(Comp2, I1, V, X, W),
c_add(V, V2, V1),
subst([N1, V1, Iold1], [N1, V1, Inew1], NV, NV1),
subst([N2, V2, Iold2], [N2, V2, Inew2], NV1, NV2),
c_add(I1,Iold1,Inew1),
c_add(I2,Iold2,Inew2).
% Specific current/voltage relations for the two terminal components
iv_reln(resistor, I, V, R, W) :-
c_mult(I,c(R,0),V).
iv_reln(voltage_source, I, V, V, W).
iv_reln(isource, I, V, I, W).
iv_reln(capacitor, I, V, C, W) :-
c_mult( c(0,W * C),V,I).
iv_reln(inductor, I, V, L, W) :-
c_mult(c(0,W * L),I,V).
iv_reln(connection, I, c(0,0), L, W).
iv_reln(open, c(0,0), V, L, W).
iv_reln(diode, I, V, D, W) :- diode(D, I, V).
diode(in914, c(I,0), c(V, 0)) :-
V < -100,
DV = V + 100,
I = 10*DV.
diode(in914, c(I,0), c(V, 0)) :-
V >= -100,
V < 0.6,
I = 0.001*V.
diode(in914, c(I,0), c(V, 0)) :-
V >= 0.6,
DV = V - 0.6,
I = 100*DV.
addcomp(W, [transistor, Num, X, [N1, N2, N3]], NV, NV3, [transistor, Num, X, [N1, V1, I1], [N2, V2, I2], [N3, V3, I3]]):-
transistor(X, R, Gain),
c_add(I1, I3, IT),
c_neg(I2, IT),
c_add(Vin, V2, V1),
c_mult(I1, c(R, 0), Vin),
c_mult(I1, c(Gain, 0), I3),
subst([N1, V1, Iold1], [N1, V1, Inew1], NV, NV1),
subst([N2, V2, Iold2], [N2, V2, Inew2], NV1, NV2),
subst([N3, V3, Iold3], [N3, V3, Inew3], NV2, NV3),
subst([N4, V4, Iold4], [N4, V4, Inew4], NV3, NV4),
c_add(I1,Iold1,Inew1),
c_add(I2,Iold2,Inew2),
c_add(I3,Iold3,Inew3),
c_add(I4,Iold4,Inew4).
transistor(bc108, 1000, 100).
addcomp(W, [transformer, Num, X, [N1, N2, N3, N4]], NV, NV4, [transformer, Num, X, [N1, V1, I1], [N2, V2, I2], [N3, V3, I3], [N4, V4, I4]]):-
c_neg(I1, I2),
c_neg(I3, I4),
c_add(Vin, V2, V1),
c_add(Vout, V4, V3),
c_mult(Vout, c(X, 0), Vin),
c_mult(I1, c(X, 0), I4),
subst([N1, V1, Iold1], [N1, V1, Inew1], NV, NV1),
subst([N2, V2, Iold2], [N2, V2, Inew2], NV1, NV2),
subst([N3, V3, Iold3], [N3, V3, Inew3], NV2, NV3),
subst([N4, V4, Iold4], [N4, V4, Inew4], NV3, NV4),
c_add(I1,Iold1,Inew1),
c_add(I2,Iold2,Inew2),
c_add(I3,Iold3,Inew3),
c_add(I4,Iold4,Inew4).
subst(X, Y, [X|L1], [Y|L1]) :- !.
subst(X, Y, [Z|L1], [Z|L2]) :-
subst(X,Y,L1,L2).
subst(X, Y, [], L2) :-
printf("Node list incomplete\n", []).
% ***** COMPLEX NUMBER ARITHMETIC *****
c_mult(c(Re1,Im1),c(Re2,Im2),c(Re3,Im3)) :-
Re3 = Re1*Re2 - Im1*Im2,
Im3 = Re1*Im2 + Re2*Im1.
c_add(c(Re1,Im1),c(Re2,Im2),c(Re3,Im3)) :-
Re3 = Re1 + Re2,
Im3 = Im1 + Im2.
c_neg(c(Re,Im),c(Re1,Im1)) :-
Re1 = -Re, Im1 = -Im .
c_eq(c(Re1,Im1),c(Re2,Im2)) :-
Re1 = Re2, Im1 = Im2 .
c_real(c(Re,Im),Re).
c_imag(c(Re,Im),Im).
% ****** PRINTOUT ROUTINES ******
format_print(H, []) :-
!,
all_print(H).
% If no selection is given then
% print out all nodes.
format_print(H, Selection) :-
selective_print(H, Selection).
% Otherwise print the selection.
selective_print(Ls, [N|Ns]) :-
print_nodes(Ls, N, 0),
print_comps(Ls, N),
selective_print(Ls, Ns).
selective_print(Ls, []).
print_nodes([[Comp, Num, X|Nodes]|L], N1, Heading_flag_1) :-
member(N1, Nodes),
Heading_flag_2 = Heading_flag_1 + 1,
heading(N1, Heading_flag_2),
all_print([[Comp, Num, X|Nodes]]),
print_nodes(L, N1, Heading_flag_2).
print_nodes([[Comp, Num, X|Nodes]|L], N1, Heading_flag) :-
print_nodes(L, N1, Heading_flag).
print_nodes([], N1, Heading_flag).
print_comps([[Comp, Num, X|Nodes]|L], Num) :-
all_print([[Comp, Num, X|Nodes]]),
print_comps(L, Num).
print_comps([[Comp, Num, X|Nodes]|L], Num1) :-
print_comps(L, Num1).
print_comps([], Num).
heading(N, 1) :-
!,
printf("\nCOMPONENT CONNECTIONS TO NODE %\n", [N]).
heading(N, X).
member(N1, [[N1, V, I]|Ls]).
member(N1, [[N2, V, I]|Ls]) :-
member(N1, Ls).
write_units(resistor, X) :-
printf("% Ohms",[X]).
write_units(capacitor, X) :-
printf("% Farads",[X]).
write_units(inductor, X) :-
printf("% Henrys", [X]).
write_units(current_source, X) :-
printf("% Ampere", [X]).
write_units(voltage_source, X) :-
printf("% Volts", [X]).
write_units(diode, X) :-
printf("type %", [X]).
write_units(transistor, X) :-
printf("type % (base, emitter, collector)", [X]).
write_units(transformer, X) :-
printf("ratio of %", [X]).
all_print([[Comp, Num, X|Nodes]|L]) :-
printf("% %: ", [Comp, Num]),
write_units(Comp, X),
printf("\n", []),
pr_nodes(Nodes),
all_print(L).
all_print([]).
pr_nodes([[N1, V1, I1]|X]) :-
printf(" Node %\n", [N1]),
printf(" Voltage %\n", [V1]),
printf(" Current %\n", [I1]),
pr_nodes(X).
pr_nodes([]) :-
printf("\n", []).
go1:-
W = 10,
Vs = 10,
R = 10,
L = 0.9,
C = 0.007,
circuit_solve(W,
[
[voltage_source,v1,c(Vs,0),[n1,n7]],
[resistor,r1,R,[n1,n2]],
[resistor,r2,R,[n1,n3]],
[resistor,r3,R,[n1,n4]],
[resistor,r4,R,[n1,n5]],
[resistor,r5,R,[n1,n6]],
[inductor,l1,L,[n2,n7]],
[inductor,l2,L,[n3,n7]],
[inductor,l3,L,[n4,n7]],
[inductor,l4,L,[n5,n7]],
[inductor,l5,L,[n6,n7]],
[capacitor,c1,C,[n2,n3]],
[capacitor,c2,C,[n2,n4]],
[capacitor,c3,C,[n2,n5]],
[capacitor,c4,C,[n2,n6]],
[capacitor,c5,C,[n3,n4]],
[capacitor,c6,C,[n3,n5]],
[capacitor,c7,C,[n3,n6]],
[capacitor,c8,C,[n4,n5]],
[capacitor,c9,C,[n4,n6]],
[capacitor,c10,C,[n5,n6]]
],
[n7],
[r1, r3, l1, l3, c8, l5]
).
% Output:
% resistor r1: 10 Ohms
% Node n1
% Voltage c(10, 0)
% Current c(0.552486, -0.497238)
% Node n2
% Voltage c(4.475138, 4.972376)
% Current c(-0.552486, 0.497238)
%
% resistor r3: 10 Ohms
% Node n1
% Voltage c(10, 0)
% Current c(0.552486, -0.497238)
% Node n4
% Voltage c(4.475138, 4.972376)
% Current c(-0.552486, 0.497238)
%
% inductor l1: 0.9 Henrys
% Node n2
% Voltage c(4.475138, 4.972376)
% Current c(0.552486, -0.497238)
% Node n7
% Voltage c(0, 0)
% Current c(-0.552486, 0.497238)
%
% inductor l3: 0.9 Henrys
% Node n4
% Voltage c(4.475138, 4.972376)
% Current c(0.552486, -0.497238)
% Node n7
% Voltage c(0, 0)
% Current c(-0.552486, 0.497238)
%
% capacitor c8: 0.007 Farads
% Node n4
% Voltage c(4.475138, 4.972376)
% Current c(0, 0)
% Node n5
% Voltage c(4.475138, 4.972376)
% Current c(0, 0)
%
% inductor l5: 0.9 Henrys
% Node n6
% Voltage c(4.475138, 4.972376)
% Current c(0.552486, -0.497238)
% Node n7
% Voltage c(0, 0)
% Current c(-0.552486, 0.497238)
%
go2:-
Vs = 10,
Tr1 = 5,
Tr2 = 0.2,
R1 = 1000,
R2 = 200,
R3 = 50,
R4 = 30,
circuit_solve(W,
[
[voltage_source, v1, c(Vs,0),[in, ground1]],
[resistor, r1, R2, [in, n1]],
[transformer, t1, Tr1,[n1, ground1, n2, ground2]],
[resistor, r2, R1, [n2, base]],
[transistor, q1, bc108, [base, n3, n4]],
[resistor, r3, R2, [n3, ground2]],
[resistor, r3, R2, [n4, ground2]],
[transformer, t2, Tr2,[n4, ground2, out, ground3]],
[resistor, r5, R4, [out, ground3]]
],
[ground1, ground2, ground3],
[n4, out]).
% Output:
% COMPONENT CONNECTIONS TO NODE n4
% transistor q1: type bc108 (base, emitter, collector)
% Node base
% Voltage c(1.909222, 0)
% Current c(9.005764e-005, 0)
% Node n3
% Voltage c(1.819164, 0)
% Current c(-0.009096, 0)
% Node n4
% Voltage c(-0.010742, 0)
% Current c(0.009006, 0)
%
% resistor r3: 200 Ohms
% Node n4
% Voltage c(-0.010742, 0)
% Current c(-5.371231e-005, 0)
% Node ground2
% Voltage c(0, 0)
% Current c(5.371231e-005, 0)
%
% transformer t2: ratio of 0.2
% Node n4
% Voltage c(-0.010742, 0)
% Current c(-0.008952, 0)
% Node ground2
% Voltage c(0, 0)
% Current c(0.008952, 0)
% Node out
% Voltage c(-0.053712, 0)
% Current c(0.00179, 0)
% Node ground3
% Voltage c(0, 0)
% Current c(-0.00179, 0)
%
%
% COMPONENT CONNECTIONS TO NODE out
% transformer t2: ratio of 0.2
% Node n4
% Voltage c(-0.010742, 0)
% Current c(-0.008952, 0)
% Node ground2
% Voltage c(0, 0)
% Current c(0.008952, 0)
% Node out
% Voltage c(-0.053712, 0)
% Current c(0.00179, 0)
% Node ground3
% Voltage c(0, 0)
% Current c(-0.00179, 0)
%
% resistor r5: 30 Ohms
% Node out
% Voltage c(-0.053712, 0)
% Current c(-0.00179, 0)
% Node ground3
% Voltage c(0, 0)
% Current c(0.00179, 0)
%
?- printf("\n>>> Sample goals: go1/0, go2/0\n", []).