From 098b54d46b7b0d0c07a3804e0626ab6341c5b173 Mon Sep 17 00:00:00 2001 From: glenux Date: Mon, 31 Aug 2009 13:19:28 +0000 Subject: [PATCH] somme-produit: Initial import. --- Makefile | 36 +++++++++ README.compilation | 22 +++++ README.enonce | 61 ++++++++++++++ somme_produit.pl | 197 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 316 insertions(+) create mode 100644 Makefile create mode 100644 README.compilation create mode 100644 README.enonce create mode 100644 somme_produit.pl diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e28ebbc --- /dev/null +++ b/Makefile @@ -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 diff --git a/README.compilation b/README.compilation new file mode 100644 index 0000000..d635b58 --- /dev/null +++ b/README.compilation @@ -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 diff --git a/README.enonce b/README.enonce new file mode 100644 index 0000000..082a082 --- /dev/null +++ b/README.enonce @@ -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... + diff --git a/somme_produit.pl b/somme_produit.pl new file mode 100644 index 0000000..1f6dec1 --- /dev/null +++ b/somme_produit.pl @@ -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 ...)