somme-produit: Initial import.

This commit is contained in:
glenux 2009-08-31 13:19:28 +00:00
commit 098b54d46b
4 changed files with 316 additions and 0 deletions

36
Makefile Normal file
View file

@ -0,0 +1,36 @@
#
# PROJET DE LOGIQUE : Monsieur Somme et Madame Produit.
# Magistère Stic, Module Logique. 2002-2003.
# Cours de R. Treinen et H.Comon
#
#-------------------------------------------------------------------%
#
# Projet de Glenn ROLLAND
#
# pour plus de détails au sujet du raisonnement, voir le
# fichier README.enonce
#
# pour la compilation et execution du projet, veuillez
# vous référer au fichier README.compilation
PROLOGC=gplc
GDATE := $(shell date +"-%Y-%m-%d_r%H")
GFILENAME := ../GSP$(GDATE).tar.bz2
LOCALDIR = $(shell pwd)
PRJNAME = gsp
PLFILES := somme_produit.pl
all: clean compile
clean:
@rm -f $(PRJNAME)
compile: $(PLFILES)
$(PROLOGC) $(PLFILES) -o $(PRJNAME)
package: clean storefile
storefile:
tar -cjvf $(GFILENAME) -C ../ GSP
mv $(GFILENAME) ../Archives

22
README.compilation Normal file
View file

@ -0,0 +1,22 @@
#
# PROJET DE LOGIQUE : Monsieur Somme et Madame Produit.
# Magistère Stic, Module Logique. 2002-2003.
# Cours de R. Treinen et H.Comon
#
#-------------------------------------------------------------------%
#
# Projet de Glenn ROLLAND
#
# pour plus de détails au sujet du raisonnement, voir le
# fichier README.enonce
#
# pour la compilation et execution du projet, veuillez
# vous référer au fichier README.compilation
Pour compiler le projet, taper
make
Pour l'executer
./gsp

61
README.enonce Normal file
View file

@ -0,0 +1,61 @@
#
# PROJET DE LOGIQUE : Monsieur Somme et Madame Produit.
# Magistère Stic, Module Logique. 2002-2003.
# Cours de R. Treinen et H.Comon
#
#-------------------------------------------------------------------%
#
# Projet de Glenn ROLLAND
#
# pour plus de détails au sujet du raisonnement, voir le
# fichier README.enonce
#
# pour la compilation et execution du projet, veuillez
# vous référer au fichier README.compilation
Analyse de l'énoncé et raisonnement suivi :
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
P : Je ne connais pas ces deux entiers.
--
le produit de P peut se décomposer d'au moins 2 facons
différentes
(on pourrait avoir P=24=12*2=6*4 mais pas 22=11*2)
PROLOG> on supprimera donc tous les P ayant une unique
PROLOG> décomposition (produit de deux nombres premiers
PROLOG> par exemple)
--
S : Je savais que vous ne les connaissiez pas.
--
Donc la somme S ne s'écrit pas comme somme de deux nombres
dont le produit aurait été supprimé tout à l'heure
PROLOG> pour un S donné, on fabrique ses diverses
PROLOG> "décomposition", on calcule les produits possibles
PROLOG> et on retire le nombres tel que:
PROLOG> - le produit ne se décompose que d'une seule maniére
PROLOG> donc que la taille de la liste des décompositions du
PROLOG> produit est <2 (ou <3 si l'on duplique chaque prod)
PROLOG> - la somme est paire (car le produit a une décomp.
PROLOG> unique, et c'est plus rapide à vérifier que de faire
PROLOG> la recherche de décomp. de P).
--
P : Alors je les connais.
--
Donc le produit P ne se décompose plus que d'une facon unique
et il ne figure plus qu'une seule fois dans la liste
des produits associés a chaque somme réstante...
PROLOG> on supprime donc tous les produits pouvant être
PROLOG> associés à plusieurs sommes
--
S: Alors je les connais aussi.
--
Les solutions sont donc les sommes auxquelles ne sont associés
qu'un seul produit, apres avoir passé tous les 'filtres' des étapes
précédentes...

197
somme_produit.pl Normal file
View file

@ -0,0 +1,197 @@
%
% PROJET DE LOGIQUE : Monsieur Somme et Madame Produit.
% Magistère Stic, Module Logique. 2002-2003.
% Cours de R. Treinen et H.Comon
%
%-------------------------------------------------------------------%
%
% Projet de Glenn ROLLAND
%
% pour plus de détails au sujet du raisonnement, voir le
% fichier README.enonce
%
% pour la compilation et execution du projet, veuillez
% vous référer au fichier README.compilation
%
%*******************************************************************%
% QUELQUES OUTILS POUR PLUS TARD...
%*******************************************************************%
% racine(N,P) est vrai si P est la racine du premier carré
% suppérieur à N.
racine(N,S) :- racine_aux(N, 0, 1, 1, S).
racine_aux(N, Sqrt, Pair, Somme, Ans) :-
Somme =< N,
Sqrt1 is Sqrt + 1,
Pair1 is Pair + 2,
Somme1 is Somme + Pair,
racine_aux(N, Sqrt1, Pair1, Somme1, Ans).
racine_aux(N, Sqrt, Pair, Somme, Sqrt) :- Somme > N.
% est_premier(N) est vrai si N est un nombre premier.
est_premier(2).
est_premier(N):-
N > 1,
racine(N,J),
U is J+1,
est_premier(2, U, N).
est_premier(I, I, _):-!.
est_premier(I, J, N):-
N mod I > 0,
I1 is I + 1,
est_premier(I1, J, N).
% est_diviseur(Nombre,Diviseur) est vrai si Diviseur divise Nombre.
est_diviseur(Nombre,Nombre).
est_diviseur(Nombre,1) :- Nombre > 0.
est_diviseur(Nombre,Diviseur) :- Nombre > 0,
Diviseur>0,
NNb is Nombre - Diviseur,
est_diviseur(NNb,Diviseur).
%*******************************************************************%
% FONCTIONS PERMETTANT D'ENUMERER LES NOMBRES QUI
% ONT LA MEME SOMME
%*******************************************************************%
asc_somme_liste_aux([],[],Debut,Final) :-
Debut > (Final // 2).
% On s'arrete si l'on dépasse la borne (Final / 2) car sinon
% on retrouvera la même liste de chiffres chiffres que AList,
% à l'envers dans la liste DList
asc_somme_liste_aux([Debut|AList],[Diff|DList],Debut,Final) :-
Debut =< (Final // 2),
Diff is Final - Debut,
Mid is Debut+1,
asc_somme_liste_aux(AList,DList,Mid,Final),!.
% On énumère les nombres de facon décroissante
somme_liste(Somme,AList,DList) :-
asc_somme_liste_aux(AList,DList,2,Somme).
% AList et DList contiennent à la fin les listes tel que si on
% prend le ieme élèment de AList et le ieme élément de DList,
% alors leur somme est Somme
%*******************************************************************%
% FONCTIONS PERMETTANT D ENUMERER LES NOMBRES QUI
% ONT LE MEME PRODUIT
%*******************************************************************%
prod_liste(Final,AList,DList) :-
prod_liste_aux(AList,DList,2,Final).
prod_liste_aux([],[],Debut,Final) :-
racine(Final,V), Debut > V.
prod_liste_aux(AList,DList,Debut,Final) :-
racine(Final,V), Debut =< V,
(\+ est_diviseur(Final,Debut)),
Suivant is Debut+1,
prod_liste_aux(AList,DList,Suivant,Final).
prod_liste_aux([A|AList],[D|DList],Debut,Final) :-
racine(Final,V), Debut =< V,
est_diviseur(Final,Debut),
A is Debut, D is (Final // A),
Suivant is Debut+1,
prod_liste_aux(AList,DList,Suivant,Final),!.
%*******************************************************************%
% GENERATION DE LA LISTE DES PRODUITS
%*******************************************************************%
% gen_prod_liste(A,D,P) est vrai lorsque P[i]=A[i]*D[i] pour tout i.
gen_prod_liste([],[],[]).
gen_prod_liste([A|AList],[D|DList],[P|ProdList]) :- P is A*D,
gen_prod_liste(AList,DList,ProdList).
%*******************************************************************%
% GENERATION DE LA LISTE DES SOMMES
%*******************************************************************%
% gen_somme_liste(A,D,S) est vrai lorsque S[i]=A[i]+D[i] pour tout i.
gen_somme_liste([],[],[]).
gen_somme_liste([A|AList],[D|DList],[S|SommeList]) :- S is A + D,
gen_somme_liste(AList,DList,SommeList).
%*******************************************************************%
% VERIFICATIONS SUR LES PRODUITS
%*******************************************************************%
prod_non_unique(P) :- prod_liste(P,PL1,PL2),
length(PL1,Longueur1),
Longueur1 > 1.
tous_non_uniques([]).
tous_non_uniques([P|ListP]) :- prod_non_unique(P),
tous_non_uniques(ListP).
%******************************************************************%
% VERIFICATION QU'UNE VALEUR DE SOMME PEUT CORRESPONDRE
% A UNE SOLUTION
%******************************************************************%
% les sommes paires ne sont pas validees
valide_somme(S,[]) :- M is S mod 2, M = 0,fail.
% les sommes impaires égales à un premier plus 2 ne sont pas
% validees
valide_somme(S,[]) :- M is S mod 2, M=1,
U is S-2, est_premier(U), fail.
% pour le reste des sommes, on calcule.
valide_somme(S,ProdList) :- M is S mod 2, M=1,
somme_liste(S,S1,S2),
gen_prod_liste(S1,S2,ProdList),
tous_non_uniques(ProdList).
% TROP LENT
enlever_non_valide([],[]).
enlever_non_valide([S|SList],ResultList) :-
(\+ valide_somme(S,ProdList)),
enlever_non_valide(SList,ResultList),!.
enlever_non_valide([S|SList],[R|ResultList]) :-
valide_somme(S,ProdList),
R is S,
enlever_non_valide(SList,ResultList),!.
%******************************************************************%
% VERIFICATION QU'UN PRODUIT NE CORRESPOND QU'A 1 SEULE
% DECOMPOSITION (EN SOMME) EXISTANTE (car dans ce cas P
% connait ces 2 nombres)
%*******************************************************************%
% TROP LENT
somme_unique_for_prod(P) :- prod_liste(P,P1,P2),
gen_somme_liste(P1,P2,SommeList),
enlever_non_valide(SommeList,FiltreeSommes),
length(FiltreeSommes,Longueur),
Longueur<2.
somme_unique_for_prod_liste([],[]).
somme_unique_for_prod_liste([P|ProdList], ResultList) :-
(\+ somme_unique_for_prod(P)),
somme_unique_for_prod_liste(ProdList,ResultList).
somme_unique_for_prod_liste([P|ProdList],[R|ResultList]) :-
somme_unique_for_prod(P),
R is P,
somme_unique_for_prod_liste(ProdList,ResultList).
somme_produit(S,R) :- valide_somme(S,ProdList),
somme_unique_for_prod_liste(ProdList,[R|RList]),
length(RList,L),
L = 0.
/************************************************************
enumeration
***********************************************************/
% fonction qui énumere les solutions (X,Y) telles que X+Y < S
% enumere(S ...)