Guest User

Untitled

a guest
May 24th, 2018
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Prolog 6.87 KB | None | 0 0
  1. /****************************************************************************/
  2. /* Modules                                                                  */
  3. /****************************************************************************/
  4.  
  5. % Pour maplist().
  6. :- use_module(library(apply)).
  7.  
  8. /****************************************************************************/
  9. /* Petits utilitaires.                                                      */
  10. /****************************************************************************/
  11.  
  12. % Opérateur ?=.
  13. :- op(20, xfy, ?=).
  14.  
  15. % Crée une liste à partir d'un élément.
  16. repeter(X, N, [X|Reste]) :- N > 0, I is N - 1, repeter(X, I, Reste), !.
  17. repeter(_, 0, []).
  18.  
  19. % Prend deux termes et les met en opérande de ?=.
  20. appairer(T1, T2, R) :- R = T1 ?= T2.
  21.  
  22. % Ecriture conditionnelle.
  23. ecrire(X) :- write(X).
  24.  
  25. /****************************************************************************/
  26. /* Remplacement d'une variable par un terme.                                */
  27. /****************************************************************************/
  28.  
  29. % Remplacement de variable dans un terme.
  30. remplace_variable(Terme, Variable, Entree, Sortie) :-
  31.     Variable == Entree,
  32.     Sortie = Terme,
  33.     !
  34.     .
  35.  
  36. % Remplacement de variable dans un terme.
  37. remplace_variable(Terme, Variable, Entree, Sortie) :-
  38.     compound(Entree),
  39.     Entree =.. [Foncteur|Args],
  40.     length(Args, Longueur),
  41.     repeter(Terme, Longueur, ListeT),
  42.     repeter(Variable, Longueur, ListeV),
  43.     maplist(remplace_variable, ListeT, ListeV, Args, Resultat),
  44.     append([Foncteur], Resultat, ListeSortie),
  45.     Sortie =.. ListeSortie,
  46.     !
  47.     .
  48.  
  49. % Dans les autres cas de remplacement, aucune modification.
  50. remplace_variable(_, _, Entree, Sortie) :- Sortie = Entree.
  51.  
  52. /****************************************************************************/
  53. /* Test d'occurrence.                                                       */
  54. /****************************************************************************/
  55.  
  56. % Test d'occurrence quand le terme est une variable.
  57. occur_check(V, T) :- var(V), V == T, !.
  58.  
  59. % Test d'occurrence quand le terme est un prédicat.
  60. occur_check(V, T) :-
  61.     compound(T),
  62.     T =.. [_|Args],
  63.     occur_check_liste(V, Args),
  64.     !
  65.     .
  66.  
  67. % Test d'occurrence dans une liste de termes.
  68. occur_check_liste(V, [Tete|Reste]) :- occur_check(V, Tete) ; occur_check_liste(V, Reste).
  69. occur_check_liste(_, []) :- fail.
  70.  
  71. /****************************************************************************/
  72. /* Détermination de la règle de calcul applicable.                          */
  73. /****************************************************************************/
  74.  
  75. % Test d'application de la règle Rename.
  76. regle(X ?= T, rename) :- var(X), var(T), !.
  77.  
  78. % Test d'application de la règle Simplify.
  79. regle(X ?= T, simplify) :- var(X), atom(T), !.
  80.  
  81. % Test d'application de la règle Expand.
  82. regle(X ?= T, expand) :- var(X), compound(T), \+ occur_check(X, T), !.
  83.  
  84. % Test d'application de la règle Check.
  85. regle(X ?= T, check) :- var(X), X \== T, occur_check(X, T), !.
  86.  
  87. % Test d'application de la règle Orient.
  88. regle(T ?= X, orient) :- var(X), compound(T), !.
  89.  
  90. % Test d'application de la règle Decompose.
  91. regle(A ?= B, decompose) :-
  92.     compound(A), compound(B),
  93.     A =.. [F1|Args1],
  94.     B =.. [F1|Args2],
  95.     same_length(Args1, Args2),
  96.     !
  97.     .
  98.  
  99. % Test d'application de la règle Clash.
  100. regle(A ?= B, clash) :-
  101.     compound(A), compound(B),
  102.     A =.. [F1|Args1],
  103.     B =.. [F2|Args2],
  104.     (
  105.         F1 \== F2 ;
  106.         \+ same_length(Args1, Args2)
  107.     ),
  108.     !
  109.     .
  110.  
  111. /****************************************************************************/
  112. /* Unification des termes en utilisant les règles de calcul de l'algo.      */
  113. /****************************************************************************/
  114.  
  115. % Application de la règle Rename.
  116. reduit(rename, X ?= T, P, Q) :- remplace_variable(T, X, P, Q), !.
  117.  
  118. % Application de la règle Simplify.
  119. reduit(simplify, X ?= T, P, Q) :- remplace_variable(T, X, P, Q), !.
  120.  
  121. % Application de la règle Expand.
  122. reduit(expand, X ?= T, P, Q) :- remplace_variable(T, X, P, Q), !.
  123.  
  124. % Application de la règle Check.
  125. reduit(check, _, _, Q) :- Q = echec.
  126.  
  127. % Application de la règle Orient.
  128. reduit(orient, T ?= X, P, Q) :- append([X ?= T], P, Q), !.
  129.  
  130. % Application de la règle Decompose.
  131. reduit(decompose, A ?= B, P, Q) :-
  132.     A =.. [_|Args1],
  133.     B =.. [_|Args2],
  134.     maplist(appairer, Args1, Args2, Paires),
  135.     append(Paires, P, Q),
  136.     !
  137.     .
  138.  
  139. % Application de la règle Clash.
  140. reduit(clash, _, _, Q) :- Q = echec.
  141.  
  142. /****************************************************************************/
  143. /* Différentes stratégies d'unification.                                    */
  144. /****************************************************************************/
  145.  
  146. % Stratégie dépendant de l'implémentation de Prolog.
  147. choix_premier([Tete|Reste], Resultat, Equation, Regle) :-
  148.     regle(Tete, Regle),
  149.     Equation = Tete,
  150.     reduit(Regle, Tete, Reste, Resultat),
  151.     !
  152.     .
  153.  
  154. % Choix avec la pondération des règles optimale.
  155. choix_pondere_optimal(Termes, Resultat, Equation, Regle) :-
  156.     choix_pondere(
  157.         Termes, Resultat, Equation, Regle,
  158.         [clash, check, rename, simplify, orient, decompose, expand]
  159.     ).
  160.  
  161. % Choix avec pondération des règles. Il y a toujours forcément une règle qui s'applique.
  162. choix_pondere(_, _, _, _, []) :- fail.
  163. choix_pondere(Termes, Resultat, Equation, RegleChoisie, [Regle|Regles]) :-
  164.     (
  165.         choix_premier(Termes, Resultat, Equation, Regle),
  166.         RegleChoisie = Regle
  167.     );
  168.     choix_pondere(Termes, Resultat, Equation, RegleChoisie, Regles)
  169.     .
  170.  
  171. /****************************************************************************/
  172. /* Prédicat exécutant l'algorithme de Martelli-Montanari.                   */
  173. /****************************************************************************/
  174.  
  175. % Stratégie par défaut.
  176. unifie(Termes) :- unifie(Termes, choix_premier).
  177.  
  178. % Une liste vide est unifiée.
  179. unifie([], _) :- nl.
  180.  
  181. % Unification d'un terme.
  182. unifie(Termes, Strategie) :-
  183.     ecrire('system : '), ecrire(Termes), nl,
  184.     call(Strategie, Termes, Resultat, Equation, Regle),
  185.     ecrire(Regle), ecrire(' : '), ecrire(Equation), nl,
  186.     Resultat \== echec,
  187.     unifie(Resultat, Strategie),
  188.     !
  189.     .
  190.  
  191. /****************************************************************************/
  192. /* Tests                                                                    */
  193. /****************************************************************************/
  194.  
  195. % unifie([Z ?= f(X), f(X,Y) ?= f(g(Z),h(a))], choix_pondere_optimal).
  196.  
  197. /****************************************************************************/
  198. /* Menu principal.                                                          */
  199. /****************************************************************************/
  200.  
  201. unification :-
  202.     write('Entrez une liste de termes a unifier : '),
  203.     read_term(A, [variable_names(L)]), !,
  204.     writeln(L),
  205.     write('Choisissez une strategie : '),
  206.     read_term(B, []), !,
  207.     unifie(A, B)
  208.     .
Add Comment
Please, Sign In to add comment