Comment puis-je simuler une boucle while en Prolog par immuable conditions?
Donc, fondamentalement, je suis en train de simuler un code C en Prolog.
Il est facile de simuler boucle while en Prolog est Ici le cas:
Code C:
int a = 1;
while(N)
{
N--;
a++;
}
Prologue code:
prolog_while(0) : !
prolog_while(N, A) :
N1 is N -1,
A1 is A + 1,
prolog_while(N1, A1).
Un problème est comment faire pour simuler une boucle while en Prolog par immuable conditions?
Est ici le cas:
int n = 1;
int a = 1;
while(1)
{
if (N==0)
goto while_end;
else
{
N--; A++;
}
}
Ou
while(1)
{
if (N==0)
break;
else
{
N--; A++;
}
}
Je sais que c'est un peu bizarre, mais, fondamentalement, ce genre de C code est automatiquement généré par une source de l'outil d'analyse de code, donc je m'en occupe...
En gros comment puis-je simuler dans le Prologue? Est-il faisable?
Quelqu'un pourrait-il me donner un peu d'aide?
===================mise à jour============
J'ai essayé d'écrire quelques Prologue du code dans ce sens, mais, fondamentalement, je ne sais toujours pas comment gérer test de la clause.
main :- loop_entry(2, 1), write(N), nl, write(A), nl.
do(A, N, A1, N1) :- A1 is (A + 1), N1 is (N - 1).
test(N) :- ... <----- # How to write this part?
loop_entry(N, A) :-
test(N),
do(A, N, A1, N1),
loop_entry(N1,A1).
main/1
de travail? Les variables N
et A
ne sont pas instanciés n'importe où, donc write/1
ne finissent par écrit le nom de l'anonyme variable--quelque chose comme _G978
. Plus important encore, la coupe de l'opérateur !
ne signifie pas false
, et ne fonctionne pas comme un "break" pour N = 0 -> !
ne fonctionne pas pour induire l'échec de test/1
.OriginalL'auteur lllllllllllll | 2014-04-05
Vous devez vous connecter pour publier un commentaire.
Le moyen le plus évident de faire une boucle infinie en Prolog est avec
repeat/0
, et il ressemble à ceci:devient
Le vrai problème devient alors: qu'il n'y a pas de solution évidente analogique à
goto
oubreak
en Prolog. Donc, je serais enclin à chercher un modèle comme ceci:et la convertir en Prolog comme ceci:
Vous aurez bien sûr besoin d'ajouter vos variables locales en tant que paramètres à
loop_entry/0
et de mettre en œuvretest
, mais de cette façon, lorsquetest
échoue, la boucle naturellement.Suivant votre exemple avec N et A conduit à ce genre de chose:
Le "test" dans ce cas est simplement
N > 0
. Si ce n'est pas vrai, le prédicat échouera et vous pouvez aller sur avec vie le Prologue.Edit #2. Si vous souhaitez que les résultats (N et A) puis ajouter des paramètres supplémentaires pour les valeurs que vous souhaitez retourner et d'en ajouter un alinéa:
Vous pouvez ajouter un cut après que la condition ou de les mettre à l'inverse de la condition dans cette nouvelle clause.
J'ai édité la réponse à montrer comment le faire.
Salut Daniel, Merci pour votre réponse, mais, fondamentalement, comment puis-je obtenir les résultats(je veux dire en finale A et N), parce que quand N = 0, N >0 échoue et tous les précédents appel récursif de loop_entry seront vouées à l'échec et puis prolog programme va échouer....
Je suis désolé, mais je ne suis pas très familier avec Prolog, pardonnez-moi si je pose une question stupide...
J'ai édité la réponse encore une fois. 🙂 Garder la foi, vous allez y arriver.
OriginalL'auteur Daniel Lyons
Pas très différent de votre prolog_while prédicat:
Mais plus probablement, vous voulez que la valeur finale d'Un être à la disposition de l'appelant de ce prédicat, donc vous devez le retourner via un argument supplémentaire:
OriginalL'auteur jschimpf
De la Logtalk de la bibliothèque standard:
Pour les autres traditionnels des constructions en boucle, voir:
https://github.com/LogtalkDotOrg/logtalk3/blob/master/library/loopp.lgt
https://github.com/LogtalkDotOrg/logtalk3/blob/master/library/loop.lgt
Z = 1, whiledo(Z < 4,Z=Z+1)
semble toujours à l'échec. Est-il une documentation qui explique comment utiliser ce prédicat?Non pas que le but
Z=Z+1
(ouZ is Z+1
, ce que vous avez voulu écrire) est toujours faux. Ainsi, la définition ci-dessus n'est pas utilisable dans ce cas. Mais voir l'autre "boucle" méta-prédicats dans les liens dans ma réponse. E. g.loop::forto(Z, 1, 4, write(Z))
va écrire1234
.OriginalL'auteur Paulo Moura
Afin de mettre en œuvre tout en boucles dans le Prologue, j'ai écrit un petit interprète pour un langage impératif.
À l'aide de cet interprète, tandis que la boucle peut être écrit comme ceci:
OriginalL'auteur Anderson Green