IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Prolog Discussion :

Difficulté à "inverser" une fonction


Sujet :

Prolog

  1. #1
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 679
    Points
    18 679
    Par défaut Difficulté à "inverser" une fonction
    Salut,


    j'ai cette "fonction" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    compatible(?N,?L1,?L2)
    % on vérifie que les différences de N avec les éléments contenus dans L1 ne figurent pas dans L2
    % sachant que N >= max L1
    % et que L2 est l'ensemble des différences entre les éléments de L1
    je réussis dans les cas suivants :
    - les trois arguments sont définis
    - N est une variable
    - L2 est une variable


    mais j'ai des problèmes pour retrouver L1 à partir de N et L2

    j'ai essayé cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    compatible_arg2(_,[_],[]).
    compatible_arg2(_,L1,[N|L]) :-
    	head(L1,A),
    	random(0,3000,A),
    	!,
    	queue(L1,Q),
    	head(Q,B),
    	plus(N,B,A),
    	!,
    	compatible(_,Q,L),
    	compatible(_,[A|Q],[N|L]).

    mais je me retrouve avec trop d'éléments dans L1


    si quelqu'un a une solution, ou peux me guider un peu... je suis preneur
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  2. #2
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Dans l'absolu, il n'y a pas une infinité de solutions pour L1 ?

    Quand tu écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    compatible_arg2(_,L1,[N|L]) :-
    	head(L1,A),
    	%random(0,3000,A),
    	%!,
    	queue(L1,Q),
    	...
    Tu veux dire que L1 peut s'écrire [A | Q] c'est ça ?
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  3. #3
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 679
    Points
    18 679
    Par défaut
    Citation Envoyé par Trap D
    Dans l'absolu, il n'y a pas une infinité de solutions pour L1 ?
    ben si... d'où le random

    Citation Envoyé par Trap D
    Tu veux dire que L1 peut s'écrire [A | Q] c'est ça ?

    oui...
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  4. #4
    Rédacteur
    Avatar de pcaboche
    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    2 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Singapour

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 785
    Points : 9 716
    Points
    9 716
    Par défaut
    Citation Envoyé par gorgonite
    ben si... d'où le random
    Oui... mais non !

    En Prolog, une infinité de solutions, c'est une infinité de solutions, c'est pas une solution prise au hasard.

    Ton problème m'a l'air vraiment complexe et tiré par les cheveux.
    "On en a vu poser les armes avant de se tirer une balle dans le pied..."
    -- pydévelop

    Derniers articles:

    (SQL Server) Introduction à la gestion des droits
    (UML) Souplesse et modularité grâce aux Design Patterns
    (UML) Le Pattern Etat
    Autres articles...

  5. #5
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 679
    Points
    18 679
    Par défaut
    Citation Envoyé par pcaboche
    En Prolog, une infinité de solutions, c'est une infinité de solutions, c'est pas une solution prise au hasard.
    mais sinon il veut pas instancier...

    Citation Envoyé par pcaboche
    Ton problème m'a l'air vraiment complexe et tiré par les cheveux.

    c'est un tout petit morceau d'un projet... pour valider un cours très dur dans un très bon master
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 5
    Points : 5
    Points
    5
    Par défaut
    Si il y a une infinité de solution, pourquoi ne pas plutôt interdire les cas qui ne marche pas (et qui sont en quantité finie) ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    compatible(+N,-L1,+L2) :- calc_all_differences(N,L1,L2),
                                        !,fail.
    où la fonction "calc_all_differences/3" est celle définie dans ton précédant topic : http://www.developpez.net/forums/sho...d.php?t=216433

  7. #7
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 679
    Points
    18 679
    Par défaut
    Citation Envoyé par Amon-Râ
    Si il y a une infinité de solution, pourquoi ne pas plutôt interdire les cas qui ne marche pas (et qui sont en quantité finie) ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    compatible(+N,-L1,+L2) :- calc_all_differences(N,L1,L2),
                                        !,fail.
    où la fonction "calc_all_differences/3" est celle définie dans ton précédant topic : http://www.developpez.net/forums/sho...d.php?t=216433

    certes, mais on finit par tomber sur un cas non géré, car dans le calcul on tombe avec deux arguments non instanciés
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  8. #8
    Membre confirmé Avatar de billynirvana
    Homme Profil pro
    Architecte technique
    Inscrit en
    Décembre 2004
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2004
    Messages : 472
    Points : 552
    Points
    552
    Par défaut
    Pourrais-tu être plus explicite pour l'énoncé de ton problème. Je crois que tu cherche à trouver le complémentaire de N dans L1, et mettre la solution dans L2. Je me trompe?

    Si c'est le cas, moi je le fais comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    complementaire(nil, e2, nil)->;
    complementaire(x.e1, e2, x.e3)->
    	hors_de(x, e2)!
    	complementaire(e1, e2, e3);
    complementaire(x.e1, e2, e3)->
    	complementaire(e1, e2, e3);
     
    hors_de(x, nil)->;
    hors_de(x, y.l)->
    	dif(x, y)
    	hors_de(x, l);
     
    /*
    > complementaire(1.2.3.nil, 1.4.3.nil, e);
    {e=2.nil}
    */

    Cdlt

  9. #9
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 679
    Points
    18 679
    Par défaut
    @billynirvana: nan pas du tout


    mon problème actuel est le suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    compatible(?N,?L1,?L2)
    % on vérifie que les différences de N avec les éléments contenus dans L1 ne figurent pas dans L2
    % sachant que N >= max L1
    % et que L2 est l'ensemble des différences entre les éléments de L1
    et je veux pouvoir inverser L1... en ayant bien sûr des valeurs instanciées dans N et L2
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  10. #10
    Rédacteur
    Avatar de pcaboche
    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    2 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Singapour

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 785
    Points : 9 716
    Points
    9 716
    Par défaut
    Citation Envoyé par gorgonite
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    % on vérifie que les différences de N avec les éléments contenus dans L1 ne figurent pas dans L2
    % sachant que N >= max L1
    % et que L2 est l'ensemble des différences entre les éléments de L1
    Il va falloir traduire chacune des règles énoncées :

    Citation Envoyé par gorgonite
    % on vérifie que les différences de N avec les éléments contenus dans L1 ne figurent pas dans L2
    Dans ce cas, il nous faut un prédicat pour faire la liste des nombres interdits, quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    prohibited(N, L2, Prohibited) :-
      maplist( m(N), L2, Prohibited).
     
    m(A,B,C) :-
      C is A-B.
    Comme ça, à la génération, on fera :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    \+memberchk(I, Prohibited),
    Citation Envoyé par gorgonite
    % sachant que N >= max L1
    Dans ce cas, à la la génération, on aura:
    et donc, avec ce qui est écrit plus haut :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    between(0, N, I),
    \+memberchk(I, Prohibited),
    Citation Envoyé par gorgonite
    % et que L2 est l'ensemble des différences entre les éléments de L1
    Cela implique deux choses :

    - Que pour chaque élément I généré, on a bien les différences entre I et les éléments précédemment générés qui se trouvent toutes dans L2 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    checkDiffs(I, Gen, Diffs) :-
      member(E, Gen),
      D1 is E-I,
      D2 is I-E,
      \+ (memberchk(D1, Diffs) , memberchk(D2, Diffs)),
      !,
      fail.
     
    checkDiffs(_, _, _).
    - Comme L2 est l'ensemble des différences entre les éléments de L1, si la liste généré vérifie cette propriété, alors c'est une solution. Il faut donc un prédicat pour vérifier cette propriété :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    checkAllDiffs(L, Diffs) :-
      checkAllDiffs(Diffs, L, L, L).
     
     
    checkAllDiffs([], [], _, _) :- !.
     
    checkAllDiffs(Diffs, [H1|Q1], [H2|Q2], L2) :- 
      !,
      D1 is H1-H2,
      D2 is H2-H1,
      delete(Diffs, D1, Tdiff),
      delete(Tdiff, D2, NDiffs),
      checkAllDiffs(NDiffs, [H1|Q1], Q2, L2).
     
     
    checkAllDiffs(Diffs, [_|Q1], [], L2) :- 
      checkAllDiffs(Diffs, Q1, L2, L2).
    J'espère que ça aide, parce que je ne suis pas sûr d'avoir tout compris au problème (il aurait fallu quelques exemples).

    Sur ce, bonne chance !
    "On en a vu poser les armes avant de se tirer une balle dans le pied..."
    -- pydévelop

    Derniers articles:

    (SQL Server) Introduction à la gestion des droits
    (UML) Souplesse et modularité grâce aux Design Patterns
    (UML) Le Pattern Etat
    Autres articles...

  11. #11
    Membre confirmé Avatar de billynirvana
    Homme Profil pro
    Architecte technique
    Inscrit en
    Décembre 2004
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2004
    Messages : 472
    Points : 552
    Points
    552
    Par défaut
    Je n'ai toujours rien compris, mais pour inverser une liste, moi je fais comme ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    %%%%%%%%%%%%%%%%%%%%
    %- Inverse une liste l1 et met le resultat dans l2 -%
     
    inverser(l1, l2)->
    	inv(l1, nil, l2);
     
    inv(nil, l0, l0)->;	%- Passage final de parametres -%
    inv(x.l1, l0, l2)->
    	inv(l1, x.l0, l2);
     
    /*
    > inverser(1.2.3.4.5.nil, l);
    {l=5.4.3.2.1.nil}
    */

  12. #12
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 679
    Points
    18 679
    Par défaut
    Citation Envoyé par pcaboche
    J'espère que ça aide, parce que je ne suis pas sûr d'avoir tout compris au problème (il aurait fallu quelques exemples).

    Ben en fait, non...

    voilà les exemples :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    compatible(3,[1,0],[1]).
    Yes
     
     
    compatible(N,[1,0],[1]).
    N = 3
     
     
    compatible(3,[1,0],L).
    L = [1]
    jusque là j'y arrive... mais je veux aussi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    compatible(3,L,[1]).
    L = [1,0]
    L = [7,8]
    ...
    pour chaque argument non instancié je passe par une méthode ad-hoc (compatible_argN), et donc j'ai un problème sur compatible_arg2
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  13. #13
    Rédacteur
    Avatar de pcaboche
    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    2 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Singapour

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 785
    Points : 9 716
    Points
    9 716
    Par défaut
    Citation Envoyé par gorgonite
    jusque là j'y arrive... mais je veux aussi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    compatible(3,L,[1]).
     L = [1,0]
     L = [7,8]
     ...
    L=[7,8] ne respecte pas la condition N >= max L1.



    Citation Envoyé par gorgonite
    Ben en fait, non...
    Ah ouais ? T'es sûr ?

    Alors regarde ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    compatible(N, L1, L2) :-
      nonvar(N),
      var(L1),
      nonvar(L2),
      compatible_arg2(N, L1, L2).
     
     
     
    compatible_arg2(N,L1,L2) :-
      maplist( m(N), L2, Prohibited),
      genList(N, [], L2, Prohibited, L1).
     
     
    m(A,B,C) :-
      C is A-B.
     
     
     
     
    genList(_, Gen, Diffs, _, Gen) :-
      checkAllDiffs(Gen, Diffs).
     
     
     
    genList(Max, Gen, Diffs, Prohibited, R) :-
       between(0, Max, I),
       \+memberchk(I, Prohibited),
     
       checkDiffs(I, Gen, Diffs),
       genList(Max, [I|Gen], Diffs, Prohibited, R).
     
     
     
    checkDiffs(I, Gen, Diffs) :-
      member(E, Gen),
      D1 is abs(E-I),
      \+ memberchk(D1, Diffs),
      !,
      fail.
     
     
    checkDiffs(_, _, _).
     
     
     
     
    checkAllDiffs(L, Diffs) :-
      checkAllDiffs(Diffs, L, L, L).
     
     
    checkAllDiffs([], [], _, _) :- !.
     
    checkAllDiffs(Diffs, [H1|Q1], [H2|Q2], L2) :- 
      !,
      D1 is H1-H2,
      D2 is H2-H1,
      delete(Diffs, D1, Tdiff),
      delete(Tdiff, D2, NDiffs),
      checkAllDiffs(NDiffs, [H1|Q1], Q2, L2).
     
     
    checkAllDiffs(Diffs, [_|Q1], [], L2) :- 
      checkAllDiffs(Diffs, Q1, L2, L2).
    Tests :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    1 ?- compatible(5, L, [1]).
     
    L = [1, 0] ;
     
    L = [0, 1] ;
     
    L = [2, 1] ;
     
    L = [1, 2] ;
     
    L = [3, 2] ;
     
    L = [2, 3] ;
     
    No
    2 ?- compatible(5, L, [1,2]).
     
    L = [2, 1, 0] ;
     
    L = [1, 2, 0] ;
     
    L = [2, 0, 1] ;
     
    L = [0, 2, 1] ;
     
    L = [1, 0, 2] ;
     
    L = [0, 1, 2] ;
     
    No
    Après, si tu ne veux que les résultats triés, tu modifies juste un peu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    compatible_arg2(N,L1,L2) :-
      maplist( m(N), L2, Prohibited),
      genList(N, [], L2, Prohibited, L1),
      msort(L1, L1).
    "On en a vu poser les armes avant de se tirer une balle dans le pied..."
    -- pydévelop

    Derniers articles:

    (SQL Server) Introduction à la gestion des droits
    (UML) Souplesse et modularité grâce aux Design Patterns
    (UML) Le Pattern Etat
    Autres articles...

  14. #14
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 679
    Points
    18 679
    Par défaut
    Citation Envoyé par pcaboche
    L=[7,8] ne respecte pas la condition N >= max L1.
    en effet... faudra que je relise mieux la prochaine fois


    Citation Envoyé par pcaboche
    Ah ouais ? T'es sûr ?

    je fais jeter un coup d'oeil là-dessus

    ps: quand le projet sera officiellement clos, à savoir en milieu de semaine prochaine, je pourrais vous mettre le sujet et ma "solution"... si jamais la rubrique manque de sources ou autres


    [EDIT]ça marche... mais semblerait que mon analyse était fausse, car même avec tous les arguments inversibles, il ne reconstruit rien
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

Discussions similaires

  1. [PHP 5.3] [POO] : faire une fonction quote
    Par gwendoline-bricout dans le forum Langage
    Réponses: 7
    Dernier message: 20/02/2014, 10h41
  2. Opération inverse d'une fonction
    Par fadiese_1 dans le forum Delphi
    Réponses: 6
    Dernier message: 26/12/2006, 18h53
  3. Inverse de la fonction QUOTE() ?
    Par __fabrice dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 13/07/2006, 10h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo