Hi Alex, On Wed, Feb 9, 2022 at 9:53 PM Alexander Burger <a...@software-lab.de> wrote:
> > > > > : (? (factorial @X 120)) > > > > -> NIL > > > > > > How should be declared factorial primitive to be compatible with reverse > > lookup? > > I have not tried. How is it in real Prolog? > In modern prolog you use this form: fac(0,1). fac(N,X) :- N #> 0, A #= N - 1, X #= N * X1, fac(A,X1). but it depends on CLP(FD) which is not implemented in pilog I'm afraid. A workaround is using an accumulator for both then number and the factorial, assuming factorial is defined for numbers > 0: factorial(0,1). factorial(X, XFact) :- f(X, 1, 1, XFact). f(N, N, F, F) :- !. f(N, N0, F0, F) :- succ(N0, N1), F1 is F0 * N1, f(N, N1, F1, F). But it seems pilog doesn't manage properly this either: (be fa (0 1)) (be fa (@X @XF) (f @X 1 1 @XF)) (be f (@N @N @F @F) T) (be f (@N @N0 @F0 @F) (^ @N1 (inc (-> @N0))) (^ @F1 (* (-> @F0) (-> @N1))) (f @N @N1 @F1 @F)) Now asking for factorial of 6 I get: : (? (fa 6 @X)) @X=720 -> NIL the other way works perfectly: : (? (fa @X 6)) @X=3 -> NIL : (? (fa @X 1)) @X=0 @X=1 -> NIL but it haves problems when asking for factorial of 0: : (? (fa 0 @X)) @X=1 2454 No memory $ Similar behaviour when asking for factorial of 1, this time pilogs appears to hang out without doing nothing but if you press ctrl-C you get a clue about where it stopped: : (? (fa 1 @X)) @X=1 (inc (-> @N0)) ! (inc (-> @N0)) ! (inc (-> @N0)) ! (-> @N1) ! (inc (-> @N0)) ! (inc (-> @N0)) ! (inc (-> @N0)) .. (several ctrl-C hits) $ Maybe introducing a predicate asserting N should be greater than 0 but I didn't find the way. A similar problem appears when defining list_length predicate, in prolog you get: ll([],0). ll([H|T],N) :- ll(T,N1), N is N1 + 1. ?- ll(X,5). X = [_606, _612, _618, _624, _630] . ?- ll(X,Y). X = [], Y = 0 ; X = [_860], Y = 1 ; X = [_860, _866], Y = 2 ; X = [_860, _866, _872], Y = 3 ; X = [_860, _866, _872, _878], Y = 4 ; X = [_860, _866, _872, _878, _884], Y = 5 ; X = [_860, _866, _872, _878, _884, _890], Y = 6 . when trying to translate it to pilog I get: (be ll (NIL 0)) (be ll ((@ . @T) @N) (ll @T @N0) (^ @N (inc (-> @N0)))) (? (ll NIL @X)) @X=0 -> NIL (? (ll (1) @X)) @X=1 -> NIL (? (ll (b a) @X)) #-> this is b(a) ? this is the syntax used in "be" then it should be X=1 @X=2 -> NIL (? (ll (b (a)) @X)) #-> same here, semantics is not clear for me @X=2 -> NIL (? (ll @L 2)) # this apparently hangs @L=(@ @) (? (ll @L @M)) @L=NIL @M=0 @L=(@) @M=1 @L=(@ @) @M=2 @L=(@ @ @) @M=3 @L=(@ @ @ @) @M=4 .. which is ok > To take an example a bit simpler than the factorial function, you could > start > with addition as: > > That's a nice implementation of logic + specially your next post which solves +(X,Y,4) for example. Still there's something I don't fully understand, I will comment it in your next post. > But where will that end? Should we also handle two or three variables, > generating all combinations of natural numbers? This could surely be done > (similar to what 'append/3' does for lists), but I never saw a need for > that. > > Not really a pragmatical use or need, but it could be useful in some situations. I really was testing how similar is pilog to real prolog. > The second one. But I think it does not matter, you can pass any pattern > to a > predicate, it is matched in any case. > > but the way it matches it's important because you have to match compound terms not treating them as lists > > what is supposed to mean (be p (r (b))) if anything? > > Yeah, there is no "meaning". It is just a pattern. > > : (? (p @A @B)) > @A=r @B=(b) > > but that matching corresponds to a prolog list or a prolog term? I mean, that matches with prolog [r b] or with prolog r(b) ? > > > May you explain the estructure of a pilog environment (and the use of > unify > > function) > > The environments are nested association lists, with numbers for the levels > and > then the symbols for the values at these levels. > > and levels are related to backtracking somehow? regards