2017-10-18 10 views
3

-je utiliser passé swiprolog et ont un knowlegdebase avec quelques faits comme:règle affirmation de SWI-Prolog Liste

det(the). 
det(a). 
adjective(quick). 
adjective(brown). 
noun(cat). 
noun(fox). 
prep(on). 
prep(with). 
verb(sat). 
verb(ran). 

et j'ai une règle

generate_grammar(GrammarList):- 
     new_rule(GrammarList). 

Cette règle est transmis une liste avec un nombre inconnu d'éléments [det,noun,verb,prep] et devrait générer une nouvelle règle pour la "grammaire" passée. La nouvelle règle devrait générer une "phrase" avec les faits donnés et la nouvelle grammaire. J'ai testé certaines choses mais je n'ai pas réussi.

Je pense que la règle souhaitée ressemble à:

new_rule(List) :- 
    Head=sentence(X), 
    Body=[List] 
    dynamic(Head), 
    assertz(Head :- Body). 

Je ne sais pas comment faire ce droit. Alors, comment cela pourrait-il être fait?

Merci d'avance!

+0

Avez-vous vu encore l'opérateur univ? 'X = .. [det, D]' unifie 'X' avec' det (D) '. Cela pourrait vous être utile pour ce projet. –

+0

Hey Daniel, oui j'ai effectivement utilisé cet opérateur dans ce projet mais je n'ai aucune idée de la façon de traiter la liste – J4ck

+2

Vous ne savez pas vraiment comment construire les règles; cela semble faire ce que vous avez demandé: 'maplist (appel, [det, adjectif, nom, verbe], Sentence).' –

Répondre

4

Il est probablement possible d'ajouter dynamiquement des règles au magasin en utilisant assertz/1 et. Al. Je n'ai jamais vraiment eu à le faire, car il est trop facile de faire évaluer Prolog par d'autres structures de données.

Pour votre base de données particulière, tous vos faits ont arité 1, donc nous pouvons simplement utiliser call/2 pour les évaluer:

?- call(det, D). 
D = the ; 
D = a. 

Tirer parti, vous pouvez résoudre le problème en utilisant maplist/2 sans structures intermédiaires réelles:

sentence(Grammar, Words) :- maplist(call, Grammar, Words). 

Son utilisation:

?- maplist(call, [det,adjective,noun,verb], Sentence). 
Sentence = [the, quick, cat, sat] ; 
Sentence = [the, quick, cat, ran] ; 
Sentence = [the, quick, fox, sat] ; 
Sentence = [the, quick, fox, ran] ; 
Sentence = [the, brown, cat, sat] ; 
Sentence = [the, brown, cat, ran] ; 
Sentence = [the, brown, fox, sat] ; 
Sentence = [the, brown, fox, ran] ; 
Sentence = [a, quick, cat, sat] ; 
Sentence = [a, quick, cat, ran] ; 
Sentence = [a, quick, fox, sat] ; 
Sentence = [a, quick, fox, ran] ; 
Sentence = [a, brown, cat, sat] ; 
Sentence = [a, brown, cat, ran] ; 
Sentence = [a, brown, fox, sat] ; 
Sentence = [a, brown, fox, ran]. 
+0

En prolog cela fonctionne très bien, mais j'utilise aussi python avec pyswip pour les requêtes.Si je fais une requête avec 'result = list (prolog.query ('phrase (X)'))', ma sortie est quelque chose comme: '{'A': [Atom ('396421'), Atom (' 397317 '), Atom (' 393093 ')]}] '. Pour les autres requêtes sans maplist cela fonctionne bien. As-tu une idée de ce que je fais de mal? – J4ck

+0

@ J4ck Je n'ai jamais utilisé pyswip et je ne connais pas la première chose à propos de ce problème. Il semble que vous ayez à faire quelque chose pour obtenir la valeur de l'atome séparément. –

4

Vous pouvez réellement transformer cela en une véritable relation en ajoutant des faits pour les catégories syntaxiques connues:

category(det). 
category(adjective). 
category(noun). 
category(prep). 
category(verb). 

Ensuite, vous pouvez décrire une relation entre les catégories et les mots qui appartiennent à ces catégories:

cat_word(C,W) :- 
    category(C), 
    call(C,W). 

?- cat_word(C,W). 
C = det, 
W = the ; 
C = det, 
W = a ; 
C = adjective, 
W = quick ; 
C = adjective, 
W = brown . 
. 
. 
. 

Enfin , suite à l'idée présentée par Lyon @ Daniel, vous pouvez appliquer maplist/3 à cat_word/2:

grammar_sentence(G,S) :- 
    maplist(cat_word,G,S). 

Dans la grammaire à la direction condamner cette donne e e mêmes résultats que phrase sous-jacente Daniels/2:

?- grammar_sentence([det,adjective,noun,verb],S). 
S = [the, quick, cat, sat] ; 
S = [the, quick, cat, ran] ; 
S = [the, quick, fox, sat] ; 
S = [the, quick, fox, ran] ; 
S = [the, brown, cat, sat] ; 
S = [the, brown, cat, ran] ; 
S = [the, brown, fox, sat] ; 
S = [the, brown, fox, ran] ; 
S = [a, quick, cat, sat] ; 
S = [a, quick, cat, ran] ; 
S = [a, quick, fox, sat] ; 
S = [a, quick, fox, ran] ; 
S = [a, brown, cat, sat] ; 
S = [a, brown, cat, ran] ; 
S = [a, brown, fox, sat] ; 
S = [a, brown, fox, ran]. 

Mais grammar_sentence/2 peut également être utilisé dans la phrase à la direction de la grammaire:

?- grammar_sentence(G,[the,quick,cat,sat]). 
G = [det, adjective, noun, verb] ; 
false. 

?- grammar_sentence(G,[the,cat,sat]). 
G = [det, noun, verb] ; 
false. 
+2

C'est une amélioration significative! –