We've already established that I'm an established slacker. Out of the 17 or so AI lectures we've taken so far, I've only attended the first [lol]. I'm much better when it comes to classes, though, where we actually learn something, so I've attended like 4 out of 6.
Also, I usually only "study" for university 4 times a year: before the midterms and before the finals. Given that the AI mid-term is next Sunday, I had to see what all the fuss is about, so I started reading our course notes and exploring Prolog. And man, what an enjoyable paradigm and language. It's really enlightening to explore problem solving from an entirely different perspective - I encourage you to try it out if you hadn't already.
Given the following very simple rule, "You talk about someone either if you know him or you know someone who talks about him", the exercise asks you to create a prolog representation of it for the following And/Or tree:
So I quickly came up with this:
knows(bill, jane).knows(jane, pat).knows(jane, fred).knows(fred, bill).talks_about_r(X,Y):- knows(X,Y).talks_about_r(X,Y):- knows(X,Z), talks_about_r(Z,Y).
It recursed infinitely whenever I queried it with:
?- talks_about_r(X,Y).
Given how inexperienced I am, I couldn't figure out why except by running and tracing it. Can you?
Think about it...
...
Gave up?
Here's a sample run:
X = billY = jane ;X = janeY = pat ;X = janeY = fred ;X = fredY = bill ;X = billY = pat ;X = billY = fred ;X = billY = bill ;X = billY = jane ;X = billY = pat ;X = billY = fred ;X = billY = bill ;X = billY = jane ;X = billY = pat ;X = billY = fred ;X = billY = bill ;X = billY = jane ;X = billY = pat ;X = billY = fred ;X = billY = bill ;X = billY = jane ;X = billY = pat ;X = billY = fred ;X = billY = bill ;X = billY = jane ;
Even after taking a look at the above run, I couldn't find out what's going exactly. The derivation tree revealed what's going on:
You can see that the last derived node takes us to "talks_about(bill, Y)", which is going to be broken into 2 branches: "knows(bill, Y)" and "knows(bill, Y), talks_about_r(bill, Y)". Given that bill knows jane, the right branch takes us back to the point: "knows(bill, jane), talks_about_r(jane, Y)" and so on and on and on...[lol]
You can imagine that for a nublet like myself this thingy took quite some time to discover [grin]. I haven't really thought of a simple and elegant solution to prevent this yet, because I'm done for today - perhaps tomorrow. Until then, feel free to tell me your solution if you happen to know one.
So now I've added the 2nd thing to the list of things that bring me back to n00ber zone: Prolog (The first being leetox, of course).
Muhammad out.
Definitely agreed. I really liked learning Haskell a few years ago. Teaches you to look at similar problems in a different way. Definitely must be one of the more compact quicksort implementations ever!
I've also just finished a course covering Lambda Calculus - not really any good for applied programming, but it's one of best ways to explore what programming really means. It's beautiful to see how you can put all the constructs together to show properties of pretty much every language currently used. By showing those properties you can also explore why certain languages behave the way that they do.
Anyway, regarding Prolog, doesn't it's definitions of functions implicitly define an inverse? I've never studied it, but a friend of mine did a couple of years ago - and explained that it can be a real pain to work with because you can feed answers into a function in order to get the parameters back out. Something thats a bit unintuitive in C++/Java [lol]
Jack