0
votes

I'm a beginner in Prolog and really need to solve this problem in Prolog's simplest syntax possible.

I have similar to 2 tables with different product information in Prolog like this:

product(id,company,value).
prod(prodid,date,color).

and the knowledge database is like this:

TABLE 1:

product(aa11zx, alfa, 1230).
product(bb22yz, beta, 5890).
product(cc11zx, alfa, 600).
product(dd22kx, beta, 730).
product(aa22vx, delta, 800).

TABLE 2:

prod(aa11, 1-2-2015, red).
prod(aa22, 1-7-2015, green).
prod(dd22, 1-4-2015, blue).
prod(bb22, 1-3-2015, blue).
prod(cc11, 1-3-2015, green).

The 2 tables have the 1st argument in common, but there are 2 problems I need to solve:

1st: I need a rule so that it understands that the 4 first characters in "id" in table 1 is the same as the 4 characters in "prodid" in table 2.

2nd: I need a rule / question where the system can join the 2 tables by their "product id" like it can be don in Excel with "vlookup" for example.

For example a final line of a join table should be:

product2(aa11, alfa, 1230,1-2-2015, red).

Can anyone help me ?

2
Are you sure you have to design your database like this? It might be a good idea to make sure that the IDs in the two tables are actually the same, and you don't have to split off the first 4 characters. - user1812457
If the last two character of prodid in table prod are always associated with the same row, you can as well just split them off to another column. PS. Consider using more descriptive table names? - user1812457

2 Answers

0
votes

of course, the 'simplest syntax possible' is an interesting request... what about

product2(Key, Desc, Val, D-M-Y, Color) :-
    product(PKey, Desc, Val),
    sub_atom(PKey, 0,4,_, Key), % maybe: sub_atom(PKey, _,_,_, Key)
    prod(Key, D-M-Y, Color).

sub_atom/5 it's described here... note that it's case sensitive - so, if you must handle this problem, a possibility it's to make the samecase of both. When large tables are involved, better to avoid to repeat each time...

product2(Key, Desc, Val, D-M-Y, Color) :-
    product(PKey, Desc, Val),
    upcase_atom(PKey, UPKey),
    prod(Key, D-M-Y, Color),
    upcase_atom(Key, UKey),
    sub_atom(UPKey, 0,4,_, UKey).

Note the different position in the rules of the sub_atom predicate, the first case will have much better performance than the second, when prod/3 is large, since it can benefit of argument indexing... Prolog database is actually much simpler than DB engines....

0
votes

If the table design is something you can actually change, it might be better to re-design your database to something like this:

product_x_company_value(P, X, C, V).
product_date_color(P, D, C).

One thing is naming your tables of facts: since you don't have table definition syntax as in SQL for example, the fact name is one good place to describe what the columns contain. Then, keeping the ID consistent across tables makes queries much simpler. Your first problem does not exist anymore. Joining on the first column is as easy as:

product_company_value_date_color(P, Comp, V, D, Col) :-
    product_x_company_value(P, _, Comp, V),
    product_date_color(P, D, Col).

You can collect all rows using one of the predicates for collecting all solutions. See also this answer for an example of how to query and report.

PS. As also the answer of @CapelliC points out, the Prolog database is not a true relational database: column order matters, indexing is by default only on the first argument, etc. There are ways to circumvent these limitations, but you need to consider your use case. For the question as it stands this is probably a good enough answer.