So basically I am trying to simulate some C code in Prolog.
It is easy to simulate while loop in Prolog Here is the case:
C code:
int a = 1;
while(N)
{
N--;
a++;
}
Prolog code:
prolog_while(0) : !
prolog_while(N, A) :
N1 is N -1,
A1 is A + 1,
prolog_while(N1, A1).
One problem is how to simulate a while loop in Prolog with unchangeable conditions?
Here is the case:
int n = 1;
int a = 1;
while(1)
{
if (N==0)
goto while_end;
else
{
N--; A++;
}
}
Or
while(1)
{
if (N==0)
break;
else
{
N--; A++;
}
}
I know it is kinda of weird but basically these kind of C code is automatically generated by a source code analysis tool, so I have to deal with it...
Then basically how can I simulate in Prolog? Is it doable?
Could anyone give me some help?
===================update============
I tried to write some Prolog code in this way, but basically I still don't know how to handle test 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).
From the Logtalk standard library:
For other traditional loop constructs see: https://github.com/LogtalkDotOrg/logtalk3/blob/master/library/loopp.lgt https://github.com/LogtalkDotOrg/logtalk3/blob/master/library/loop.lgt
In order to implement while-loops in Prolog, I wrote a small interpreter for an imperative language.
Using this interpreter, a while-loop can be written like this:
The most obvious way to do an infinite loop in Prolog is with
repeat/0
, and it looks like this:becomes
The real problem then becomes that there's no obvious analog to
goto
orbreak
in Prolog. So I would be inclined to look for a pattern like this:and convert it to Prolog like this:
You will of course need to add your local variables as parameters to
loop_entry/0
and implementtest
, but this way whentest
fails the loop will end naturally.Following your example with N and A leads to this kind of thing:
The "test" in this case is simply
N > 0
. If it isn't true, the predicate will simply fail and you can go on with life the Prolog way.Edit #2. If you want the results (N and A) then add additional parameters for the values you want to return and add one more clause:
You can either add a cut after the condition or put the inverse condition in this new clause.
Not very different from your prolog_while predicate:
But most likely you want the final value of A be available to the caller of this predicate, so you have to return it via an additional argument: