6
votes

Concatation d'une liste de chaînes à Prolog

J'écris un traducteur Lisp to C et j'ai un problème de manipulation des chaînes. Ceci est un code qui transforme une fonction LISP unaire sur un équivalent C: xxx

maintenant, je veux lire n'importe quel nombre de fonctions et les renvoyer comme une seule chaîne. Le ci-dessus Les amusements est le meilleur que je puisse trouver, mais cela fonctionne comme ceci: xxx

pendant que je veux quelque chose comme ça: xxx

de sorte que je puisse bien swritef est dans un programme complet, entre #include s et principal (). Une solution alternative consiste à modifier le traducteur de niveau le plus élevé pour gérer la liste. On dirait current ceci: xxx

Comment puis-je faire l'un de ces deux? J'utilise Swi Prolog.


6 commentaires

La ligne d'objet mentionne Prolog, tandis que le corps de la question pose une traduction de «LISP à C». Aidez-moi à trier ce qui est quoi ici. Les extraits de code ressemblent un peu à Prolog, peut-être parce que la syntaxe DCG spéciale est confondue avec la syntaxe plus basique de Prolog. Bien que la ligne d'objet pose des questions sur "une liste de chaînes de prolog", il semble que l'analyse des chaînes contenant du code LISP est impliquée. La concaténation d'une liste de chaînes est une tâche relativement simple dans Prolog. Votre exemple de prédicat Funs / 2 suggère que vous souhaitez jetter un couple de caractères Newline entre ...


... Les chaînes consécutives sont concaténées. Si c'est la portée de la question, je peux y répondre, et nous pouvons régler la confusion des syntaxes (si nécessaire).


La traduction Lisp to c est ce que le programme fait. Le programme est écrit dans Prolog, en utilisant la syntaxe DCG pour traduire des cas individuels. La plupart du code Pays Pays Paysp, avec leur argument étant le code C résultant. Je veux deux nouvelles lignes entre les chaînes concaténées. J'espère que c'est ça.


Donc, la partie de traduction Lisp-to-c ne faisait pas vraiment partie de la question :) Idée cool cependant. Comment gérez-vous l'allocation de mémoire?


Si je connaissais la mise en œuvre spécifique de Prolog que vous utilisez, je pourrais adapter la réponse à cela. Il existe trois représentations de données de "chaînes" communes à Prolog: cordes, atomes et listes de caractères. La norme ISO indique Lecture / 1 et les prédicats associés devraient traiter un texte coché double comme des chaînes, mais en raison du support historique de cette syntaxe pour désigner des listes de caractères, les implémentations gèrent généralement le problème avec des options de syntaxe variable. .


@larsmans: Je viens de MALLOC espace pour chaque variable. Jusqu'à présent, seul #t et () sont initialisés une seule fois et j'alloque l'espace pour chaque numéro à chaque fois qu'il est utilisé, mais je prévois de conserver une liste de numéros qui sont déjà alloués et les réutilisent si nécessaire (par affirment , probablement).


4 Réponses :


1
votes

Étant donné que les chaînes de Prolog sont réellement des listes de codes de caractères, vous pouvez utiliser append dans un prédicat personnalisé qui insère également les nouvelles lignes: xxx

utilisation: xxx


4 commentaires

Funs (F, "(Définir (zéro x) 0) (Définissez (un n) 1)", []), concat_program (f, x). c'est faux.


F = ["DATA * CarZeo (Data * L) {Retour (EQ (Voiture (Voiture (L), Make_atom_int (0)));}", "DATA * ZERO (DATA * N) {RETURNE (MAKE_ATOM_INT (0), n));} "], concat_program (f, x). fonctionne. Je ne vois pas ce qui ne va pas dans le reste de votre code puisque vous n'avez pas donné la grammaire complète.


L'idée générale est correcte mais je soupçonne que les prémistions "chaînes de prolog sont réellement des listes de codes de caractères" peut être défectueuse pour la mise en œuvre de PROG. Voir cette discussion pour Swi-Prolog Strings et Concaténation: SCI .hkbu.edu.hk / scilab / doc / prolog / sec-3.20.html


@HardMath: Cela fonctionne à Swi et Sicstus. Je n'étais pas au courant des implémentations de prologs qui gèrent la chaîne d'une manière différente. L'OP peut vouloir remplacer append avec concat ou string_concat pour voir si cela fonctionne.



2
votes

Qu'en est-il de l'utilisation de la notation DCG pour ajouter les chaînes?

concat([]) --> [].
concat([List|Lists]) --> List, "\n\n", concat(Lists).


0 commentaires

4
votes

Mettre de côté pour le moment le but pour lequel il est nécessaire, écrivons un prédicat de prologique qui concatéra une liste de chaînes dans une chaîne, plaçant une double nouvelle ligne entre chaque paire de chaînes consécutives (mais pas à la fin de la chaîne de sortie, à en juger par l'exemple que Jerry posté).

SWI-PROG Manuel: Normalement, je posterais "Deep" Liens vers La documentation , mais le site SWI-PROG utilise un style d'URL qui déclenche des avertissements de script inter-sites (XSS) avec de nombreuses combinaisons de navigateur / plug-in. Donc, au lieu de cela, je vais faire référence au lien vers la section appropriée.

Section 4.22 Représentation du texte dans les chaînes indique (en partie), "Les objets de chaîne par défaut n'ont pas de représentation lexicale et ne peuvent donc être créés que en utilisant les prédicats ci-dessous ou à travers l'interface de langue étrangère. " Cela peut être un peu confus, car Swi-Prolog écrit des chaînes en tant que texte à double coté, mais lit un texte à double coté (par défaut) comme des listes de codes de caractères.

Voici le code pour un prédicat qui concaténe le Strings dans une liste, insérant un autre séparateur de chaîne entre les paires de cordes consécutives: xxx

Notez que nous avons défini deux prédicats, strçcat / 3 et strçcat / 4 . Le premier est défini en termes de ces derniers, un modèle de conception typique de PROG introduit un argument supplémentaire comme un accumulateur qui se lie à une sortie lorsque la récursivité est terminée. Une telle technique est souvent utile pour obtenir un Tail Revute Définition.

Pour utiliser le prédicat strSPCAT / 3 , nous aurions généralement besoin de construire la chaîne de séparateur avec (la séquence d'échappée pour) deux nouvelles lignes: xxx


0 commentaires

1
votes

une solution plus simple (et plus générique) que la réponse acceptée consiste à utiliser Réduire avec le paramètre existant String_ConCAT en tant que paramètre:

strings_concat(Strings, String):-
    reduce3(string_concat, Strings, "", String).


0 commentaires