% mvlpl03.pl

%  #   2.1 gestion des opérateurs

%%%%   ne pas toucher au cadrage à cause des apostrophes

nomOper(c,'l__anti-division      C                   ').
nomOper(i,'la multiplication    I                   ').
nomOper(l,'l__implication        I de Lukasiewicz    ').
nomOper(k,'la constante         K=5                 ').
nomOper(n,'la négation          N                   ').
nomOper(s,'la somme symbolique  S                   ').
nomOper(t,'la t-conorme         T                   ').

arite(c,2).
arite(i,2).
arite(l,2).
arite(k,1).
arite(n,1).
arite(s,2).
arite(t,2).

valOperUnaire(n,PAR1,PAR2,RES) :- operuN(PAR1,PAR2,RES).
valOperUnaire(k,PAR1,PAR2,RES) :- operuK(PAR1,PAR2,PAR2,RES).

valOperBinaire(c,PAR1,PAR2,TAIL,RES)   :- operbC(PAR1,PAR2,TAIL,RES).
valOperBinaire(i,PAR1,PAR2,TAIL,RES)   :- operbI(PAR1,PAR2,TAIL,RES).
valOperBinaire(l,PAR1,PAR2,TAIL,RES)   :- operbL(PAR1,PAR2,TAIL,RES).
valOperBinaire(s,PAR1,PAR2,TAIL,RES)   :- operbS(PAR1,PAR2,TAIL,RES).
valOperBinaire(t,PAR1,PAR2,TAIL,RES)   :- operbT(PAR1,PAR2,TAIL,RES).

%  #   2.2 définition des opérateurs en TPS

% n : C= Neg(A) en taille B, la négation
n :- nl, write(' syntaxe operuN(A,B,T) pour B = n(A) en taille T '),nl.
n(A,B,C) :-  operuN(A,B,C).
operuN(A,B,C) :- C is B+1-A.

% k : D = Kons(A,B) en taille C, la constante B
k :- nl, write(' syntaxe operuK(A,B,T) pour B = k(A) en taille T '),nl.
k(A,B,C) :-  operuK(A,B,C).
operuK(_,B,_,D) :- D is B.

% c : [D,E] = I(A,B) en taille C
c :- nl, write(' syntaxe operbC(A,B,T,X) ou operbC(A,B,C,[D,E])pour X = [D,E] = c(A,B) en taille T '),nl.
c(A,B,C,D) :- operbC(A,B,C,D).
operbC(1,1,C,[1,C]).
operbC(A,1,C,[1,1]) :- A>1, Cp1 is C+1, A1, operbL(A,2,C,E).
operbC(A,B,C,[0,0]) :- B>A, B>1, Cp1 is C+1, B2, operbL(A,A,C,E).
operbC(A,B,C,[D,D]) :- A>2, B>2, B1.
operbI(A,C,C,A) :- Cp1 is C+1, A1.  % pour C on trouve le min (donc l'autre)
operbI(C,B,C,B) :- B1.
operbI(A,B,C,2) :- ApB   is A+B,   Cp1 is C+1, Cp2 is C+2, ApB1, B>1, A1, B>1, Cp1 is C+1, ACp1, ApBmC is A+B-C, D is ApBmC.

% l : D = L(A,B) en taille C
l :- nl, write(' syntaxe operbL(A,B,C,D) pour D = L(A,B) en taille C '),nl.
l(A,B,C,D) :- operbL(A,B,C,D).
operbL(A,B,C,D) :- AB, Cp1 is C+1, BC, D is C.
operbS(A,B,C,D) :- Cp1 is C+1, ACp1.

cmax    :- nl, write(' ** syntaxe operbCmax(A,B,C,D)   pour D = Cmax(A,B) en taille C '),nl.
cmed    :- nl, write(' ** syntaxe operbCmed(A,B,C,D)   pour D = Cmed(A,B) en taille C '),nl.
cmin    :- nl, write(' ** syntaxe operbCmin(A,B,C,D)   pour D = Cmin(A,B) en taille C '),nl.
cfromi  :- nl, write(' ** syntaxe operbCfromI(A,B,C,D) pour D = CfromI(A,B) en taille C '),nl.
ifromc  :- nl, write(' ** syntaxe operbIfromC(A,B,C,D) pour D = IfromC(A,B) en taille C '),nl.
sfromt  :- nl, write(' ** syntaxe operbSfromT(A,B,C,D) pour D = SfromT(A,B) en taille C '),nl.
tfroml  :- nl, write(' ** syntaxe operbTfromI(A,B,C,D) pour D = TfromL(A,B) en taille C '),nl.
tfroms  :- nl, write(' ** syntaxe operbTfromS(A,B,C,D) pour D = TfromS(A,B) en taille C '),nl.