After an agonizing amount of time tracking down my last bug, I finally nailed it. Apparently I had no (known) bugs remaining in my Prolog engine. Instead, I had a small typo in my Prolog program. It's going to take a while to get it ready for the CPAN because there's a fair amount of code and it's very complicated, but there will be an AI::Prolog on the CPAN. I was actually thinking about calling it AI::Logic, but the current implementation is pretty tightly tied to Prolog and I'm still dabbling with a different parser that would be more "perlish" (based on the Warren Abstract Machine, if anyone cares.)
In any event, here's one of the sample programs:
#!/usr/local/bin/perl -l use strict; use warnings; use lib '../lib/'; use aliased 'AI::Prolog::Parser'; use aliased 'AI::Prolog::Term'; use aliased 'AI::Prolog::Engine'; my $parser = Parser->new("append(X,Y,[a,b,c,d])."); my $query = Term->new($parser); my $engine = Engine->new($query,Parser->consult(append_prog())); print $engine->run; while (my $result = $engine->more) { print $result; } sub append_prog { "append([], X, X)." ."append([W|X],Y,[W|Z]) :- append(X,Y,Z)."; }
And the output:
append([],[a,b,c,d],[a,b,c,d]) append([a],[b,c,d],[a,b,c,d]) append([a,b],[c,d],[a,b,c,d]) append([a,b,c],[d],[a,b,c,d]) append([a,b,c,d],[],[a,b,c,d])
I also want a method that will allow it to return "Perlish" data structures.
So far the code seems to be running ~ 1000 LIPS (Logical Inferences Per Second) and that is with no optimization (this means it appears to run about as fast as the Java applet.) I want to wait until I have a solid test suite and some decent documentation before I start profiling and optimizing.
If you really want to see the (hideous) code, you can download it, but it's not even an alpha yet. There are only a handful of tests and no docs, but if you cd into the examples directory, you can run the three programs there (the benchmark won't make much sense.) If you have any questions, post them here.
Side note: back in 1992, it was noted that decent Prolog implementations ran at about 10,000 to 100,000 LIPS. Needless to say, I have a long way to go and I don't expect to get there unless I switch to Inline::C for some bits.
Shouldn't you have done that first?...I want to wait until I have a solid test suite and some decent documentation before I start profiling and optimizing.
Re:Not to be picky...
Ovid on 2005-01-21T15:19:00
I didn't write the tests firsts because I was porting this from W-Prolog and frankly, since I wasn't entirely certain what W-Prolog was doing half the time, I wasn't certain what I was writing tests for. However, by doing a faithful port from a known-good program, I could run them in parallel and keep the Perl one working properly. Now that it appears that I've nailed down the behavior of the Perl version, I'm writing tests. Curiously, in the process I've found a discrepancy between the Java and Perl versions that I can't explain, but that doesn't seem to have affected the results. I'll explore that more this weekend. As for why I am doing this, I guess I'll have to write up another journal entry
:) Sounds interesting...
Purdy on 2005-01-21T15:34:45
but WAY above my level of comprehension.:)
- JasonRe:Sounds interesting...
Ovid on 2005-01-21T16:05:55
Actually, I doubt it's above your level of comprehension. Logic programming isn't that hard, it's just a weird way of looking at things. For example, remember syllogisms in logic class?
All cats are mammals.
All mammals have fur.
Therefore, all cats have fur.In prolog:
mammal(cat).
furry(X):-
mammal(X),
not(shaved(X)).The
:- is read as "if" and the comma is read as "and". I'm sure you can figure out what that means :) In logic programming, you don't tell the computer how to figure things out (like you would in normal imperative programming.) Instead, you present the computer with facts and rules to infer new facts and then you just ask it questions. You don't tell it how to figure out the answers. Instead, it can figure them out for itself.
Well, when you put it like that...
Purdy on 2005-01-21T16:27:42
I actually laughed out loud about the shaved part - guess it helps to start with a simpler explanation.
I can see how it's kind of neat, especially getting computers to figure things out. I'm still stuck at seeing this, though, as a static set of switches. How is it learning or going beyond what you provide it? I mean, it seems like you're still having to provide a lot. When you say another mammal, it's only b/c you ruled that mammals have fur (and aren't shaved) that the mammal is furry. But you're still having to tell the computer it's a mammal and the rest of the logic there could have been put into an OOP model for furriness attributes.
Guess I need to revisit your previous posts.Re:Well, when you put it like that...
Aristotle on 2005-01-23T16:23:44
Have you ever written a Makefile? Then you know how this all works.:)
Re:I am curious...
Ovid on 2005-01-21T15:22:21
In the long term, the intent is to allow logic programming in Perl. However, I realize now that many people don't know what that is, so I'll write another entry to explain it. It's fascinating, but not something done much in Perl (because Perl has no native ability to do that, aside from a limited equivalent with regular expressions).
Native Logic Rules in Perl
n1vux on 2005-01-21T20:26:29
I like the sound of this. I've not tried to build SWI-Prolog and either of the XS modules that wrap it, but would like to have some Prolog-ish rulesets once in a while. The prior attempt at a Prolog-in-Perl hasn't moved in years. Starting over with the WAM (Warren Abstract Machine) Prolog engine sounds good to me. (Yes, I did some Prolog back during the AI wars.)For those that don't know what we're talking about, you might want to check out a Prolog Tutorial, there are quite a few available.
In the long term, the intent is to allow logic programming in Perl.... It's ... not something done much in Perl because Perl has no native ability to do that ... I had thought that in the truely long term that the Perl6 Rules would provide not just more elegant and efficient parsing but also LP rules.
However, the Perl6::Rules module doc doesn't hint at how to do LP, so I'll agree that LP is not natively supported today, only through the SWI-Prolog XS modules.Now that I see that SWI-Prolog is available as Debian modules, I might want to give the SWI wrappers a try (but they're not available as Debs? SWI wrappers are available as PPMs from ActiveState).
Did you notice the former MIT Press WAM book is now free-to-download for non-profit use?
Good Luck!
Re:Native Logic Rules in Perl
Ovid on 2005-01-21T20:41:54
Actually, I have downloaded the WAM book and started working with it, but I don't have as much free time as I would like. That could be a very long project and the current implementation actually works (and also appears to be based on WAM, but it doesn't fully implement it.)
Re:Native Logic Rules in Perl
n1vux on 2005-01-21T20:55:40
Ah, yes, I see your WAM link is the book's homepage. Nice article on PerlMonks, congrats.Yes, Inline::C would be a cleaner way to expedite your new WAM engine.
-Bill R
Re:Native Logic Rules in Perl
Ovid on 2005-01-21T21:23:50
Thanks for the compliment. Frankly, I didn't know if anyone would even understand what I wrote
:)