Re: [Chicken-users] Is there interest in this Prolog interpreter packaged as an egg?

2016-02-20 Thread John Cowan
Jeronimo Pellegrini scripsit:

> If you believe this would be interesting as an egg, tell me and I'll
> get it packaged!

Nice!  You should also compare it with Schelog.  Definitely do package
it as an egg.

-- 
John Cowan  http://www.ccil.org/~cowanco...@ccil.org
In the sciences, we are now uniquely privileged to sit side by side
with the giants on whose shoulders we stand.  --Gerald Holton

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


[Chicken-users] Is there interest in this Prolog interpreter packaged as an egg?

2016-02-20 Thread Jeronimo Pellegrini
Hello,

I have written a Prolog interpreter and I'd like to know if there is
interest in its availability as an egg.

http://aleph0.info/jp/software/prolog-in-scheme/

I am not sure if people will be interested, because it's really more
a pedagogical tool -- the source code is part of a tutorial -- and
not the most efficient implementation you could have of Prolog. However,
it is pretty complete: several different small interpreters are
available, each build on top of the other:

- Pure prolog: no local variables, no assertions, only plain Prolog 
  and SLD-resolution.

- Prolog w/built-ins: with an extensible set of built-in predicates.
  Only the built-ins within a list are allowed.

- Prolog w/Scheme functions: call any Scheme function from Prolog.

- Prolog w/local vars: this version has support for "IS" and local
  Prolog variables.

- Prolog w/meta-predicates: this version has support for "assert"
  and "retract".

- Prolog w/cut: this version supports cuts.

There are no macros for Prolog syntax -- it's all in Sexps, just like
Scheme.

If you believe this would be interesting as an egg, tell me and I'll
get it packaged!

J.


___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] New Egg: miniKanren

2016-02-20 Thread Jeremy Steward

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Note to the mailing list: apologies for the really long email ahead.
If this is too long please let me know and I won't do it again. I also
assume some knowledge of the Reasoned Schemer / miniKanren for my
response below, so if you do not know either then the following
descriptions may be sparse.

Hi Alex,

On 17/02/16 01:03 AM, Alex Silva wrote:
| Sorry for veering off-topic, but: As someone who has read the
| Reasoned Schemer, how would I go about learning this improved
| language?

No worries, I was also confused at first that the language had changed
as much as it had. All things considered these aren't "large" changes
but the style of code you write becomes very different on it's own as
well. If you want a deep explanation of how things work internally, I
can only suggest William Byrd's dissertation:

Original: http://gradworks.umi.com/33/80/3380156.html
Single-spaced: https://github.com/webyrd/dissertation-single-spaced

Nonetheless, to adapt to the latest version of miniKanren, you only
need to consider what I mentioned above in list form, since otherwise
pretty much all semantics are the same. I'll try to break it down and
go through it, if the mailing list will forgive me.

| 1. condi no longer exists 2. conde now behaves like condi

Basically, you just need to retrain yourself to think of using conde
wherever you would use condi before. The main difference between these
was more or less "how you search": whether you performed a depth first
search along a single branch (old conde) or depth first search
interleaved between branches (condi).

Here's an example from The Reasoned Schemer that should (hopefully)
illustrate what's gone on here:

OLD MINIKANREN
==

~(run 5 (q)
~  (conde
~((== #f q) alwayso)
~((== #t q) alwayso)
~(else fail))
~  (== #t q))

This runs forever, because the first conde line succeeds, but the
outer (== #t q) fails. Since alwayso will succeed an infinite number
of times, conde will try again, the first line will succeed, the outer
(== #t q) will fail, and so on and so on.

Instead, they introduce condi, which doesn't test the same branch in
order every time:

~(run 5 (q)
~  (condi
~((== #f q) alwayso)
~((== #t q) alwayso)
~(else fail))
~  (== #t q))

Here condi will still fail on the first branch, but instead of trying
the first branch again from scratch, will instead switch to the second
branch. This will succeed, which gives you a result. This behaviour in
general means that if an answer logically exists, miniKanren will find
it and return it eventually. This means it has better termination
guarantees, since the original conde just searches down the first
branch forever. Instead consider the latest miniKanren

LATEST MINIKANREN
=

~(run 5 (q)
~  (conde
~((== #f q) alwayso)
~((== #t q) alwayso))
~  (== #t q))

The extraneous else statement is removed, more on that below. However,
this runs exactly like the condi version above. My understanding is
that William Byrd found the stronger termination guarantees more
useful in practice than the Prolog-like behaviour of searching a
single branch again and again and again.

**NOTE** As an aside, since condi is gone, so are all, alli, etc that
were present in The Reasoned Schemer, as they are also no longer
needed (their primary use was to implement condi, IIRC).

| 3. else is removed as syntax from conde, conda, and condu

At first this one bothered me too, but I sort of warmed up to it. It
means you can't have an (else expr ...) branch in a conde, conda, or
condu expression. This makes it a little different from Scheme's cond,
however consider that "else" doesn't make much semantic sense in the
context of logic/relational programming anyways. I mean, you're just
performing a search down a set of branches in a conde expression, and
unlike cond, the else branch of a conde expression doesn't mean that
every other branch failed (this is implicit in cond, but in conde
you'll find that may not be true).

So instead of writing else branches, just write the expressions as you
would normally for any other branch. As an example, consider the
following (note I'm going to try and assume no other procedures are
defined other than unification).

Instead of:

~(define (appendo l s out)
~  (conde
~((== '() l) (== s out))
~(else
~  (fresh (a d res)
~(== `(,a . ,d) l)
~(== `(,a . ,res) out)
~(appendo d s res)

You could just write:

~(define (appendo l s out)
~  (conde
~((== '() l) (== s out))
~((fresh (a d res)
~   (== `(,a . ,d) l)
~   (== `(,a . ,res) out)
~   (appendo d s res)

Even in the old miniKanren, both of these would have worked the same.
Adding "else" as syntax is kind of redundant and makes for visual
noise. This is made somewhat worse by the