:- module(_,_).
:- use_package(clpr).
% You can also try: :- use_package(clpq).

% -------------------------------------------------------------------
% - Scalar (dot) product and systems of equations

% (x₁,x₂, …, xn) . (y₁, y₂, …, yn) = x₁ . y₁ + x₂ . y₂ +  … + xn . yn

% We represent vectors as lists of numbers: 

prod([], [], Result) :- 
	Result .=. 0.
prod([X|Xs], [Y|Ys], Result) :-
	Result .=. X * Y + Rest,
	prod(Xs, Ys, Rest).

% ?- prod([2, 3], [4, 5], K).
% ?- prod([2, 3], [4, Y2], 23).
% ?- prod([2, 7, 3], [Vx, Vy, Vz], 0).
% -> Answer is a constraint. Try also with clpq!
% ?- prod([Y,2,3],[4,X,6],32).

% ?- prod([3,1], [X,Y], 5), prod([1,8], [X,Y], 3).
% Equivalent to:
% 3x + y = 5 'and' x + 8y =3. 
% -> Systems of linear equations!


% - Solving systems of linear equations with arbitrary numbers 
% of variables and equations:

system([], _Vars, []). 
system([Co|Coefs], Vars, [Ind|Indeps]) :- 
    prod(Co, Vars, Ind),
    system(Coefs, Vars, Indeps).

% E.g., solving the previous system:
% 3x +  y = 5
%  x + 8y = 3
% ?- system([[3, 1],[1, 8]], [X, Y], [5, 3]).

% Note that we are using both Herbrand terms and constraints.

% Inequations are solved using a modified, incremental Simplex:
% ?- X + Y .=<. 4, Y .>=. 4, X .>=. 0.

% Non-liner equations are delayed:     
% ?- sin(X) .=. cos(X).
% ?- X*X + 2*X + 1 .=. 0.

% Reason: no general solving technique is known.
% CLPR solves only linear (dis)equations.

% Once equations become linear, they are handled properly:
% ?- X .=. cos(sin(Y)), Y .=. 2+Y*3.
