% Sample file for testing the HYPROLOG system
%
% Example file referred to in the course note
% Henning Christiansen: Abductive reasoning in Prolog and CHR,
% Roskilde University, Computer Science Department, 2005
% http://www.ruc.dk/~henning/KIIS05/Abduction.pdf
%
% - NB: that note does not use HYPROLOG but CHR directly,
%   but the background for the code below is explained.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Diagnosis of faults in logical circuits   %
%                                           %
% Version 1: Periodic fault assumption      %
%                                           %
%  (c) 2005, Henning Christiansen           %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% ?- hyprolog(diagnosisPeriodic).

% The file contains original circuit definitions without diagnosis
%
%     halfadderOrig/4, fulladderOrig/5
%
% and the following with diagnosis capabilities:
%
%     halfadder/4, fulladder/5
%

abducibles perfect/1, defect/1.

defect(X)  \ defect(X)  <=> true.
perfect(X) \ perfect(X) <=> true.
defect(X)  \ perfect(X) <=> true. 

disturbe(0,1).
disturbe(1,0).

not(0, 1).
not(1, 0).

and(0, 0, 0).
and(0, 1, 0).
and(1, 0, 0).
and(1, 1, 1).

xor(0, 0, 0).
xor(0, 1, 1).
xor(1, 0, 1).
xor(1, 1, 0).

or(0, 0, 0).
or(0, 1, 1).
or(1, 0, 1).
or(1, 1, 1).

not(A,X,ComponentId):-
   not(A,X),
   perfect(ComponentId).

not(A,X,ComponentId):-
   not(A,Z), disturbe(Z,X),
   defect(ComponentId).

and(A,B,X,ComponentId):-
   and(A,B,X),
   perfect(ComponentId).

and(A,B,X,ComponentId):-
   and(A,B,Z), disturbe(Z,X),
   defect(ComponentId).

or(A,B,X,ComponentId):-
   or(A,B,X),
   perfect(ComponentId).

or(A,B,X,ComponentId):-
   or(A,B,Z), disturbe(Z,X),
   defect(ComponentId).

xor(A,B,X,ComponentId):-
   xor(A,B,X),
   perfect(ComponentId).

xor(A,B,X,ComponentId):-
   xor(A,B,Z), disturbe(Z,X),
   defect(ComponentId).


% Original version of circuits without diagnosis

halfadderOrig(A, B, Carry, Sum):-
        and(A, B, Carry),
        xor(A, B, Sum).

fulladderOrig(Carryin, A, B, Carryout, Sum):-
        xor(A, B, X),
        and(A, B, Y),
        and(X, Carryin, Z),
        xor(Carryin, X, Sum),
        or(Y, Z, Carryout).

% Version with diagnosis; notice identifier on each gate

halfadder(A, B, Carry, Sum):-
        and(A, B, Carry,and0),
        xor(A, B, Sum,xor0).

fulladder(Carryin, A, B, Carryout, Sum):-
        xor(A, B, X,xor1),
        and(A, B, Y,and1),
        and(X, Carryin, Z,and2),
        xor(Carryin, X, Sum,xor2),
        or(Y, Z, Carryout,or1).

/**********************************************

TEST RUNS: 

| ?- halfadder(1,1,1,1).
perfect(and0),
defect(xor0) ? ;
no

| ?- halfadder(1,1,1,0), halfadder(1,1,1,1), halfadder(0,0,1,0).
defect(xor0),
defect(and0) ? ;
no

| ?- fulladder(1,0,1,1,1).
8 solutions

| ?- fulladder(1,0,1,1,1), fulladder(1,1,1,0,0), fulladder(0,0,0,0,1).
512 solutions

---
To see no. of solution without having to type a lot semicolons, use this
pattern:

| ?- QUERY,   write(*), fail.

Explanation: Read from inside, "write(*)" will print out a star when
a solution is found; the "fail" provokes backtracking, so this will
force Prolog to go try out all solution.
NB: Since all solutions continue into fail, Prolog will answer "No",
but the number of stars indicates the number of possible solutions.

**************************************/