173 views

Skip to first unread message

Oct 9, 2014, 2:40:09 PM10/9/14

to swi-p...@googlegroups.com

To map facts stored as tables with their attributes in a relational database to Prolog facts, each table is an object, and one can naturally choose table names as predicate names, with their attributes as parameters of the corresponding predicate.

But the question is, attributes in a table, say SQL table, are order-insensitive, while the parameters of a predicate is order sensitive. p(a,b,c) != p(b,a,c).

What I can think for such a representation is to represent all facts as

tableName(attribute1(PK, value)).

tableName(attribute2(PK, value)).

...

where PK is the PrimaryKey of the table,

and do a query using Answer Set Prolog (AnsProlog), which allows us to define conjunction of predicates in the head:

tableName(attribute1(PK, value)), tableName(attribute2(PK, value)).

Is there any better Prolog representation for this? I wish to use SWI-Prolog.

But the question is, attributes in a table, say SQL table, are order-insensitive, while the parameters of a predicate is order sensitive. p(a,b,c) != p(b,a,c).

What I can think for such a representation is to represent all facts as

tableName(attribute1(PK, value)).

tableName(attribute2(PK, value)).

...

where PK is the PrimaryKey of the table,

and do a query using Answer Set Prolog (AnsProlog), which allows us to define conjunction of predicates in the head:

tableName(attribute1(PK, value)), tableName(attribute2(PK, value)).

Is there any better Prolog representation for this? I wish to use SWI-Prolog.

Oct 9, 2014, 2:55:46 PM10/9/14

to Rex, swi-p...@googlegroups.com

representation and it fully exploits (JIT) indexing. How you _access_ it

is another matter. You could exploit SWI7 dicts and write

....,

p{a:A, b:B, c:C},

....

That would also allow for writing the following, indicating that order

is not important and you can omit columns you don't care about.

p{c:C, b:B}

Now, how does this work? Dicts are not valid goals by themselves. You

can however use goal_expansion/2 to turn them into a valid goal:

goal_expansion(Dict, Goal) :-

is_dict(Dict, p), % Dict is p{...}

Dict :< _{a:A,b:B,c:C}, !,

Goal = p(A,B,C).

Note that this gives you a similar result as ECLiPSe, which provides

read macros that allow you to declare that p{k:v, ...} maps to a term

p(...)

The only price is that, if you create p{...} dynamically, you cannot

call it. You must do expand_goal(p{...}, Goal), call(Goal).

Dicts are a quite elegant solution to this, but of course you can

also define that p(a=>A, b=>B, ...) serves this purpose using the

same goal expansion technique.

Hope this helps

--- Jan

Oct 14, 2014, 4:37:49 AM10/14/14

to swi-p...@googlegroups.com

Jan,

That's quite helpful! It is very convenient to use dicts here.

One further question is for the case when two or more attributes contain multiple values, then we need (m x n x k) lines to represent one record, where "m, n, k,.." are the number of multiple values of corresponding attributes of a record.

With my early representation as follows,

tableName(attribute1(PK, value)).

tableName(attribute2(PK, value)).

it only takes (m+n+k+...) lines to represent a record. But as Jan mentioned, this representation will not benefit from the JIT indexing.

Can we store multiple values of an attribute as a list in the dict?

for example,

p{a:[A1, A2, A3], b:[B1, B2], c:[C]}.

That's quite helpful! It is very convenient to use dicts here.

One further question is for the case when two or more attributes contain multiple values, then we need (m x n x k) lines to represent one record, where "m, n, k,.." are the number of multiple values of corresponding attributes of a record.

With my early representation as follows,

tableName(attribute1(PK, value)).

tableName(attribute2(PK, value)).

it only takes (m+n+k+...) lines to represent a record. But as Jan mentioned, this representation will not benefit from the JIT indexing.

Can we store multiple values of an attribute as a list in the dict?

for example,

p{a:[A1, A2, A3], b:[B1, B2], c:[C]}.

Oct 14, 2014, 4:58:32 AM10/14/14

to Rex, swi-p...@googlegroups.com

On 10/14/2014 10:37 AM, Rex wrote:

> Jan,

>

> That's quite helpful! It is very convenient to use dicts here.

>

> One further question is for the case when two or more attributes contain

> multiple values, then we need (m x n x k) lines to represent one record,

> where "m, n, k,.." are the number of multiple values of corresponding

> attributes of a record.

>

> With my early representation as follows,

> tableName(attribute1(PK, value)).

> tableName(attribute2(PK, value)).

>

> it only takes (m+n+k+...) lines to represent a record. But as Jan

> mentioned, this representation will not benefit from the JIT indexing.

>

> Can we store multiple values of an attribute as a list in the dict?

> for example,

> p{a:[A1, A2, A3], b:[B1, B2], c:[C]}.

I didn't suggest using dicts for storing, but for providing a nice
> Jan,

>

> That's quite helpful! It is very convenient to use dicts here.

>

> One further question is for the case when two or more attributes contain

> multiple values, then we need (m x n x k) lines to represent one record,

> where "m, n, k,.." are the number of multiple values of corresponding

> attributes of a record.

>

> With my early representation as follows,

> tableName(attribute1(PK, value)).

> tableName(attribute2(PK, value)).

>

> it only takes (m+n+k+...) lines to represent a record. But as Jan

> mentioned, this representation will not benefit from the JIT indexing.

>

> Can we store multiple values of an attribute as a list in the dict?

> for example,

> p{a:[A1, A2, A3], b:[B1, B2], c:[C]}.

frontend to the programmer. I think you got that though. Yes, you

can store values as

tableName(object, attribute, [value1, value2, ...])

That is fine if you don't want to ask the question "Which object has

value X as attribute?". If you do want to answer that question quickly,

you'll need

tableName(object, attribute, value1).

tableName(object, attribute, value2).

Of course, you also have this, which might be interesting if you have

high-arity tables. It all depends on the data, the ways you want to

access it and the famous time/space tradeof.

tableName(object, attribute, record0001).

value(record0001, value1).

value(record0001, value2).

...

That is why it is wise to abstract the access from the concrete

datastructure. That also allows you to move to an external DB,

the RDF db, etc.

Cheers --- Jan

> You received this message because you are subscribed to the Google

> Groups "SWI-Prolog" group.

> To unsubscribe from this group and stop receiving emails from it, send

> an email to swi-prolog+...@googlegroups.com

> <mailto:swi-prolog+...@googlegroups.com>.

> Visit this group at http://groups.google.com/group/swi-prolog.

> For more options, visit https://groups.google.com/d/optout.

Oct 21, 2014, 1:39:36 AM10/21/14

to swi-p...@googlegroups.com

Dear Jan,

Dict in SWI-Prolog v7 is very powerful!

For a general application of goal_expansion of Dicts, say, we have hundreds of Dicts with different attributes.

How to express the goal_expansion in a general form, so that we don't need to write hundreds of goal_expansions as follows?

Dict in SWI-Prolog v7 is very powerful!

For a general application of goal_expansion of Dicts, say, we have hundreds of Dicts with different attributes.

How to express the goal_expansion in a general form, so that we don't need to write hundreds of goal_expansions as follows?

goal_expansion(Dict, Goal) :-

is_dict(Dict, p), % Dict is p{...}

Dict :< _{a:A,b:B,c:C}, !,

Goal = p(A,B,C).

Thank you again!

On Thursday, October 9, 2014 11:55:46 AM UTC-7, Jan Wielemaker wrote:

Oct 21, 2014, 4:16:10 AM10/21/14

to Rex, swi-p...@googlegroups.com

On 10/21/2014 07:39 AM, Rex wrote:

> Dear Jan,

>

> Dict in SWI-Prolog v7 is very powerful!

>

> For a general application of goal_expansion of Dicts, say, we have

> hundreds of Dicts with different attributes.

> How to express the goal_expansion in a general form, so that we don't

> need to write hundreds of goal_expansions as follows?

>

> goal_expansion(Dict, Goal) :-

> is_dict(Dict, p), % Dict is p{...}

> Dict :< _{a:A,b:B,c:C}, !,

> Goal = p(A,B,C).

You will need some kind of declaration that tells you which predicates
> Dear Jan,

>

> Dict in SWI-Prolog v7 is very powerful!

>

> For a general application of goal_expansion of Dicts, say, we have

> hundreds of Dicts with different attributes.

> How to express the goal_expansion in a general form, so that we don't

> need to write hundreds of goal_expansions as follows?

>

> goal_expansion(Dict, Goal) :-

> is_dict(Dict, p), % Dict is p{...}

> Dict :< _{a:A,b:B,c:C}, !,

> Goal = p(A,B,C).

have which column names. So, first figure out how you would like to

write that information down (or get it from somewhere). Then you can

either generate the goal_expansion/2 clauses or write a more general one

that uses the declarations written down elsewhere. Note that the use of

goal_expansion/2 only affects compilation speed. So, for most

not-really-large applications, the performance doesn't matter very much.

In any case, the idea behind Prolog is to first think how you would like

the problem to be represented. In other words, what you would like to

type and read. You are only limited by the Prolog syntax, although

SWI-Prolog's quasi quotations allow you to embed fragments with a

totally different syntax in your source as well. Then you write a

transformation or meta-interpretation layer that makes it work.

Cheers --- Jan

Reply all

Reply to author

Forward

0 new messages

Search

Clear search

Close search

Google apps

Main menu