% Relational representation of the electrical example

% This is slightly expanded code of Example 13.12 of Section 13.3.2 of  
% Poole and Mackworth, Artificial Intelligence: foundations of
% computational agents, Cambridge University Press, 2nd Edition, 2017.
% (Or Figure 13.10 in Section 13.5.2 of the first edition, 2010).

% Copyright (c) David Poole and Alan Mackworth 2017. This program
% is released under GPL, version 3 or later; see http://www.gnu.org/licenses/gpl.html

% To load this in SWI Prolog do
%?- [elect_reln].

:- dynamic up/1, down/1.

% lit(L) is true if light L is lit.
lit(L) :-
   light(L),
   ok(L),
   live(L).

% live(W) is true if W is live (i.e., current will flow through it)
live(W) :-
   connected_to(W,W1),
   live(W1).

live(outside).

% light(L) is true if L is a light
light(l1).
light(l2).

% connected_to(W0,W1) is true if W0 is connnected to W1 such that current will
% flow from W1 to W0.

connected_to(l1,w0).
connected_to(w0,w1) :- up(s2), ok(s2).
connected_to(w0,w2) :- down(s2), ok(s2).
connected_to(w1,w3) :- up(s1), ok(s1).
connected_to(w2,w3) :- down(s1), ok(s1).
connected_to(l2,w4).
connected_to(w4,w3) :- up(s3), ok(s3).
connected_to(p1,w3).
connected_to(w3,w5) :- ok(cb1).
connected_to(p2,w6).
connected_to(w6,w5) :- ok(cb2).
connected_to(w5,outside) :- ok(outside_connection).

% up(S) is true if switch S is up
% down(S) is true if switch S is down
down(s1).
up(s2).
up(s3).

% ok(G) is true if G is working. Everything is ok:
ok(_).

% Example Queries:
% ?- light(l1).
% ?- light(l6).
% ?- up(X).
% ?- connected_to(w0,W).
% ?- connected_to(w1,W).
% ?- connected_to(Y,w3).
% ?- connected_to(Y,W).
% ?- live(w6).
% ?- live(p1).
% ?- lit(L).
% ?- lit(l2), live(p1).
% ?- live(L).
