Forum Programmation.autre Datalog

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
2
30
juil.
2014

Bonjour,
suite au commentaire parlant de racket, j'ai essayé. Je suis tombé sur le support de datalog un langage à la prolog.

J'ai donc fait l'exemple de la famille classique. J'ai appelé le papa dad, la mère mom, et les enfants son[123]. Quand je cherche à connaitre les frères de son3, j'obtiens son1 et son3 ! Je voudrais éliminer le dernier cas en ajoutant quelque chose du genre : brother(G, G) est faux ou en ajoutant dans le prédicat quelques chose du genre G != E

ancestor(A, B) :- parent(A, B).
ancestor(A, B) :-
  parent(A, C), D = C, ancestor(D, B).
mother(A,B) :- parent(A, B), female(A).
father(A,B) :- parent(A, B), male(A).

brother(G, E) :- male(G),father(P, G), mother(M,G), father(P,E), mother(M,E).


parent(dad,son1).
parent(dad,son2).
parent(dad,son3).
parent(mom,son1).
parent(mom,son2).
parent(mom,son3).


male(dad).
male(son1).
male(son3).
female(son2).
female(mom).

father(A, B)?
mother(A,son2)?
brother(A,son3)?

Si quelqu'un a une idée. Je suis preneur.

  • # Égalité fonctionne

    Posté par  . Évalué à 2.

    Si j'ajoute G=Edans la ligne brother, la question : brother(A,son3) ne trouve que A == son3.

    Mais je n'arrive toujours pas a trouver comment dire qu'on souhaite une différence… J'ai essayé : G\=E, G!=E, G<>E, etc.

  • # Sources

    Posté par  . Évalué à 1.

    Il y a les sources de ce DSL avec.

    J'avais regardé, ce n'est pas très long. Ca peut être instructif.

    • [^] # Re: Sources

      Posté par  . Évalué à 2.

      DSL ? Pardonne mon ignorance mais qu'est-ce que c'est ?

      http://fr.wikipedia.org/wiki/Domain-specific_programming_language ?

      • [^] # Re: Sources

        Posté par  . Évalué à 1.

        Oui, c'est ça.

        Ils parlent souvent de "faire un DSL" dans les langages type Lisp. Il y a plein de facilités pour faire ça.

        Ca peut être intéressant mais je trouve que souvent ça ne fait que déplacer le problème.

        Par exemple, les expressions régulières sont un DSL. C'est bien pour faire "grep" mais c'est souvent utilisé aussi pour faire du "pattern matching" alors qu'un parseur est plus approprié. On voit souvent du code pour vérifier un mail ou une url avec une expresion régluière.

        Rob Pike, l'inventeur, dit dans un article que quasiment à chaque fois qu'il tombe sur une expression régulière dans du code, l'usage est incorrect ou carrément faux.

        • [^] # Re: Sources

          Posté par  (site web personnel) . Évalué à 2.

          Comme tout DSL, il faut en connaître les limites (et ça vaut en fait aussi pour les langages soi-disant généralistes). Les expressions régulières ne font pas de bon parseurs rigoureux ni extensibles (encore que Perl6 fait des choses intéressantes à ce sujet), et ne donnent pas facilement des messages d'erreur pour trouver une erreur de syntaxe. Ceci dit, elles sont plus accessibles et rapides à utiliser, et suivant les besoins ça peut être le bon choix. Et même pour les parseurs, au fond la partie analyse lexicale utilise souvent des expressions régulières pour découper en lexèmes (avec lex et équivalents).

          • [^] # Re: Sources

            Posté par  . Évalué à 1.

            Les expressions régulières ne font pas de bon parseurs rigoureux ni extensibles (encore que Perl6 fait des choses intéressantes à ce sujet), et ne donnent pas facilement des messages d'erreur pour trouver une erreur de syntaxe.

            Il existe un débogueur d'expressions régulières avec une interface. J'ai vu ça récemment.

            Mais tu as raison, c'est une tannée à déverminer.

            En PHP, je faisais des "méta" expression régulières. J'avais un petit langage style "template" (par exemple, je remplaçais "\b(.*)\b" par "{word}"). J'avais moins d'erreurs comme ça.

            Et même pour les parseurs, au fond la partie analyse lexicale utilise souvent des expressions régulières pour découper en lexèmes (avec lex et équivalents).

            Je fais un lexeur de C++ (réduit) en ce moment.

            La première passe est un "split" de la chaine en "tokens". Je découpe entre les blancs, les virgules, la parenthèses. A la fin, j'ai un tableau de "tokens".

            Dans la deuxième phase, j'essaye de reconnaître des motifs (par exemple, les expressions encadrées par des guillemets, "<>", "[]" …). J'ai un "curseur" qui sauvegarde la position et la restaure si le motif n'est pas reconnu.

            Je parse des prototypes de fonctions pour faire de la réflection et du "duck typing" en C++ via un préprocesseur "maison".

            Ca me génère des "handlers" pour appeler les fonctions et obtenir leur description. Je fais de la sérialisation et de la comparaison d'objets automatique aussi.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.