top | item 20152319

(no title)

new4thaccount | 6 years ago

How is Prolog ideal for when you'd use SQL? I can understand it if you're talking about querying a CSV file, but the advantage to SQL is that the database with all your data natively supports SQL and it can usually run pretty fast.

Btw: what would it look like to query a small sample CSV file. Like the below example if you wanted to find all cars that are made by Ford?

Brand,Model,Year,Color/n Ford,F150,1999,Black/n Toyota,Yaris,2013,Yellow/n Ford,Mustang,1969,Blue/n

Edit: sorry for not knowing how to format HN properly and show the newline on each of the rows.

discuss

order

hjek|6 years ago

Hey, this is good practice!

First we can load the csv library, then read the rows of the csv file, and assert those rows as facts using the `car` identifier. (Doesn't mean `car` like in lisp, obviously, but automobile.)

    ?- [library(csv)],
         csv_read_file('cars.csv',Rows, [functor(car)]),
         maplist(assert, Rows).
If we want to find a Ford, then we can enter this query:

    ?- car('Ford', Model, Year, Colour).
Any capitalised word that's not in quotes is a variable in Prolog, so they can take any value. This will give us the result:

    Model = 'F150',
    Year = 1999,
    Colour = 'Black' ;
Press space, and we get another:

    Model = 'Mustang',
    Year = 1969,
    Colour = 'Blue'.
And there are no more, so it returns to the REPL.

(I should really have discarded the first line, because right now there's a car, whose brand is 'Brand', and so on. Well, well...)

If we just wanted a list of all the results, we could use the findall/3 predicate.

Something that's neat in Prolog is that you can define recursive relations. In SQL it's easy to define a parent/child relation, but what about ancestor/descendant? (Yes, you can use common table expressions, but the syntax is incredibly complicated.)

Also, you don't need to create database schemas and Prolog, and unification feels seamless as opposed to explicitly declaring the JOINs.

But, in my opinion, where Prolog really shines compared to SQL is that there just isn't that whole object-relational impedance mismatch[0].

[0]: https://en.wikipedia.org/wiki/Object-relational_impedance_mi...

Edit: Ok, my turn quiz!! Say we have these bicycles:

    Brand, Colour, Year
    Mosquito, Blue, 2010
    Raleigh, Red, 2005
    Suzuki, Red, 1998
In SQL, how would you find the names of any two brands whose bicycles have the same colour? (Don't bother with the whole CSV parsing; just assume it's already a table.)

In Prolog that would be:

    bicycle(One_brand, Colour, _),
    bicycle(Another_brand, Colour, _),
    One_brand \= Another_brand.
Maybe I just have particularly hard time understanding SQL, but I'd have to surf StackOverflow for at very least half an hour to do that in SQL. I wouldn't know where to start.

yawaramin|6 years ago

Nice quiz :-) My attempt would be:

    select b1.Brand as brand1, b2.Brand as brand2
    from bicycles as b1
    inner join bicycles as b2
    on (b1.Colour = b2.Colour)
    where b1.Brand <> b2.Brand

krackers|6 years ago

>how would you find the names of any two brands whose bicycles have the same colour?

At first glance I thought it'd just be a group by + having followed by some sort of SELECT to get the first 2 in each group. But apparently doing that top-k in each group is a nightmare in SQL [1].

[1] https://stackoverflow.com/questions/8748986/get-records-with...

new4thaccount|6 years ago

Thanks for working through my example question.

I may have to give Prolog another shot at some point!