% solution to extended lab exercises
% Bill Wilson, March 2005
%  History: March 2005    Created          Bill Wilson
%           05-Nov-2006   SWI Prolog       Bill Wilson
%                         Checked - let Bill W know about any further problems

% ----- Question 1 --------------------------- %

% vector_access(Vector, N, Value)
%   binds Value to the item in the Nth position in the Vector
%   - assumes that the Vector is represented as a list.

vector_access([First | Rest], 1, First).
vector_access([First | Rest], N, Result) :-
        N > 1,
        NewPos is N - 1,
        vector_access(Rest, NewPos, Result).

% if N < 1 or > the length of the Vector, this code fails, which is
% a reasonable thing for it to do.

% ----- Question 2 --------------------------- %

% matrix_access(Matrix, M, N, Value)
%   binds Value to the item in the (M, N)-position in the Matrix
%   - assumes that the Matrix is represented as a list of lists.

matrix_access(Matrix, M, N, Value) :-
	vector_access(Matrix, M, Row_M), % extract M-th row of Matrix
	vector_access(Row_M, N, Value).

% ----- Question 3 --------------------------- %

% vector_dot_product(Vector1, Vector2, Product)
%   binds Product to the inner product of Vector1 and Vector2
%   - assumes that vectors are represented as lists of numbers.

vector_dot_product([], [], 0).
vector_dot_product([First1 | Rest1], [First2 | Rest2], Result) :-
        vector_dot_product(Rest1, Rest2, RestResult),
        Result is RestResult + First1 * First2.

% If the vectors are of different length

% ----- Question 4 --------------------------- %

% transpose(Square, Transpose)
% Create the transpose of a matrix
% Written by Barry Drake, 2003

% Example of use:
% ?- transpose([[1,2,3],[4,5,6],[7,8,9]],X).
% X = [[1, 4, 7], [2, 5, 8], [3, 6, 9]].

transpose([[] | _], []) :- !.
transpose(Square, [Heads|RestTranspose]) :-
        remove_heads(Square, Heads, Rest),
        transpose(Rest, RestTranspose).


% remove_heads(ListOfLists, Heads, Tails)
% Break the list of lists up into a list of the heads and a list of the tails
% Helper for transpose

remove_heads([], [], []).
remove_heads([[X|RestRow]|Rest], [X|RestHeads], [RestRow|RestRest]) :-
        remove_heads(Rest, RestHeads, RestRest).

% ----- Question 5 --------------------------- %

?- atom_chars(X, ['1', '2', '3']).

X = '123'
?- atom_chars(X, ['1', '2', '3']), Y is X+1.
ERROR: is/2: Arithmetic: `123/0' is not a function

X = '123' may look like a number, but it's a string of digits.

Try "number_chars" instead:

?- number_chars(X, ['1', '2', '3']).

X = 123
?-  number_chars(X, ['1', '2', '3']), Y is X + 1.

X = 123
Y = 124

Thaaat's better.

% ------------------------------------------- %

% Bill Wilson
% 14 March 2005