:- module(_,_).

% Example of Structure Inspection: Arrays

% Alternative 'array' addition using functor/3 and arg/2
% but adding some syntactic sugar for arg/3 in 
% add_els/4

%------- Syntactic sugar definitions ------------------------
:- use_package(fsyntax).  % Use functional notation.
:- op(250,xfx,@).         % Define @ as infix operator
T@N := A :- arg(N,T,A).   % Define @ to call arg/3
:- fun_eval @ / 2.        % Evaluate all occurrences of @/2
                % Same as:  @(T,N) := A :- arg(N,T,A).
                % and       @(T,N,A) :- arg(N,T,A).
% Define array/2 to hide the call to functor:
array(A,N) :- functor(A,array,N).
:- fun_eval arith(true).  % Eval arithmetic expressions (I-1)
%------------------------------------------------------------

% Now we can define the array addition as: 

add_arr(A,B,C):-    
    array(A,N), 
    array(B,N), 
    array(C,N),
    add_els(N,A,B,C).

add_els(0,_,_,_).
add_els(I,A,B,C) :-
    I>0, 
    C@I is A@I + B@I, 
    add_els(I-1,A,B,C).

% ?- add_arr(array(1,2,3),array(4,5,6),R).
% ?- add_arr(array(1,2,3),array(4,5,6),array(5,7,9)).
% ?- add_arr(array(1,2,3),array(4,5),R).
