type(N,entier):- integer(N).
type(R,reel):- 	
        number(R),
	\+ integer(R).
type(B,booleen):- 
	B==vrai; B==faux.
type(Expression,Type):-
	Expression =.. [Op,E1,E2],
	type_op(Op,E1,E2,Type).
       
type_op(Op,E1,E2,entier):- 
        type(E1,T),
        type(E2,T),
        member(T,[entier,reel]),
        member(Op,[plus,moins,mult,div]).

type_op(Op,E1,E2,erreur):- 
        type(E1,T),
        type(E2,T),
        \+member(T,[entier,reel]),
        member(Op,[plus,moins,mult,div]).

type_op(Op,E1,E2,erreur):- 
        type(E1,T1),
        type(E2,T2),
        T1\=T2,
        member(Op,[plus,moins,mult,div]).

type_op(Op,E1,E2,booleen):-   
        type(E1,T),
        type(E2,T),
	T\==erreur,
        member(Op,[et,ou]).

type_op(Op,E1,E2,erreur):-   
        type(E1,T1),
        type(E2,T2),
	T1\=T2,
        member(Op,[et,ou]).




/*
type(plus(35,moins(mult(4,3),div(2,5))),T).
| ?- type(plus(35,moins(mult(4,3),div(2,5))),T).
T = entier ? ;
no

| ?- type(plus(35,moins(mult(4,3),et(2,5))),T).
T = erreur ? ;
no

*/
