Previous topic  Top  Next topic  Print this Topic
 

map data type

 

Mapping between Java objects and ObjectLogic

Example:
BLZ Service of the Deutsche Bundesbank, see
http://www.thomas-bayer.com/axis2/services/BLZService?wsdl
Generating the Java client for this web service results in (simplified here):

 
Java

interface BLZService {

  Details getDetails(String blz);

}

class Details {

  String bezeichnung;

  String bic;

  String ort;

  String plz;

}

 

A web service call from ObjectLogic could look like this:

?- _callWebservice("http://bundesbank/services/BLZService",
 "getDetails", [blz->"66010075"],?Result).

 

Internally the input parameters, here the single parameter “blz” is extracted from the input map and the web service is called via the generated Java client. The result is returned in a Details object. This object is mapped into a map constant term:

?Result = [bezeichnung->"Postbank Karlsruhe",
 bic->"PBNKDEFF",ort->"Karlsruhe",plz->"76127"]

 

Mapping between XML and ObjectLogic

Using both maps and lists, it would become possible to map XML directly into an ObjectLogic constant term without loosing the hierarchical structure and sequence order. This would be very similar to the mapping between XML and JSON.
Example:
XML

  <animals>    

 <dog id="1">

            <name>Rufus</name>

            <breed>labrador</breed>

      </dog>

      <dog id="2">

            <name>Marty</name>

            <breed>whippet</breed>

      </dog>

      <cat name="Matilda"/>

  </animals>

 
ObjectLogic

?X = [animals->[

 [dog->[
         [id->1,name->"Rufus",breed->"labrador"],
         [id->2,name->"Marty",breed->"whippet"]

  ],

  cat->[

         [name->"Matilda"]

  ]

 ]

   ]

 

Options parameter for built-ins

Example:

?- _queryIndex(module,[return(type),return(title),includeAll,stringMetric("Jaro")],
 "searchString",0,10,?OBJ,?TC,?SCORE,?ORDER,?OPT).

 

Using the map data type this becomes more readable to

?- _queryIndex(module,
[return->{type,title},includeAll->true,stringMetric-> "Jaro")],
"searchString",0,10,?OBJ,?TC,?SCORE,?ORDER,?OPT).

 

Result parameter for built-ins with variable content structure

Sometime built-ins need to return variable result sets depending on the options. This has already been needed in the above web service example. Another example is here also the _queryIndex/10 built-in, where the ?OPT variable returns variable a list of functions, which is hard to pass directly in ObjectLogic.

 
For the above example, the ?OPT variable currently returns things like
 ?OPT = [type("c"),title("Reparaturanleitung")]

Using the map data type, this would be instead
 ?OPT = [type->"c",title->"Reparaturanleitung"]

Specification Details

The syntax is just an overloading of the list syntax. The square brackets would contain key/value pairs instead of terms. Mixing terms and key/value pairs is forbidden, also the head/tail syntax used for lists.

Assignments

ObjectLogic syntax

Description

?X=[]

Empty list (special constant)

?X=[->]

Empty map (special constant)

?X=[1,2,3]

list

?X=[1|?Y]

List head / tail

?X=[a->1,b->2]

Map

?X=[a->{1,2,3},b->[1,2]]
equivalent to

?X=[a->1,a->2,a->3,b->[1,2]]

Multi-valued map. Note the difference between the values for a and b.

a is multi-valued, but b has a list as value.

?X = [1,a->b]  // invalid

Mixing of list terms and key value pairs is not allowed. ObjectLogic compiler must throw exception

 

Facts

p([a->1,b->2]).

Predicate p/1 with a map term as first argument

 

Rules , Queries, Built-ins

p([?X->?Y]) :- r(?X,?Y).

map in rule head

p(?Z) :- ?Z = [?X->?Y], r(?X,?Y).

same as above

?- ?M = collectmap { ?X,?Y | r(?X,?Y) }.
 
translates into:

?- _aggr_collectmap([],[?X,?Y], ?X, ?Y, ?M), r(?X,?Y)).

Aggregation collectmap to collect key/value pairs in one map
 
 

?- [a->{1,2},b->3][_memberAt(?X)->?Y].
 

returns:
?X = a, ?Y = 1
?X = a, ?Y = 2
?X = b, ?Y = 3

Extended built-in _memberAt/3 to extract keys and/or values from a map

?- [a->{1,2},b->3,c->4][_intersection([a->1, c->5])->?X].
 
returns:

?X = [a->1]

Built-in _intersection/3 to create intersection of two maps

?- [a->{1,2},b->3,c->4][_union([a->1, c->5])->?X].
 
returns:

?X = [a->{1,2},b->3,c->{4,5}]

Built-in _union/3 to create union of two maps

?- [a->{1,2},b->3,c->4] [_difference([a->1, c->5])->?X].
 
returns:

?X = [a->2,b->3,c->4]

Built-in _difference/2 to remove all key/value pairs of argument1 from argurment 0

?- [b->1,a->4,a->2][_normalize->?X].

 

returns:
?X = [a->{2,4}, b->1]

Built-in _normalize/2 to bring map in internal order

?- _map[_toType(a,2)->?X].

 

returns:
?X = [a->2]

Extended built-in _toType/4 to generate singleton map

?- ?M = [a->[b->[1,2], c->3], d->4], _memberByPath(?M,_path(a,b),?V)

returns

?V = [1,2]

Built-in _memberByPath/3 to filter with xpath expression

?- ?M = [a->[b->[1,2], c->3], d->4], _map2table(?M,?P,?I,?V).

 

returns

P      I      V

---------------

"a.b"  0      1

"a.b"  1      2

"a.c"  0      3

"d"    0      4

 

 

?- ?M = [a->[b->{1,2}, c->3], d->4], _map2table(?M,?P,?I,?V).

 

returns

P      I      V

---------------

"a.b"  0      1

"a.b"  1      2

"a.c"  0      3

"d"    0      4

Built-in _map2table/4 to convert a map to flat table. Note that list values are converted to flat table too.

?- [a->1,b->2] == [b->2,a->1].

 

returns:

true

_equals/2 should be extended to compare maps independently from the order

 

Side remark: Mapping ObjectLogic instances to and from maps

Interestingly, you can also extract all attribute values of an ObjectLogic instance into a map. It “strips” off the instance and leaves the blank attribute map.

 

Example 1 (flat):

juergen[name->"Jürgen", age->28].

?- ?M = collectmap { ?Z | ?Z=[?X,?Y], juergen[?X->?Y] }.

 
results in:
?M = [name->"Jürgen", age->28]

 

Example 2 (hierarchical):

juergen:Person[name->"Jürgen", age->28, address->ja].

ja:Address[street->"An der RaumFabrik", ort->"Durlach"].

?- ?M = collectmap { ?Z
| ((?Z=[?X,?Y], NOT ?Y:?)

     OR (?M1 = collectmap {?Z1 | ?Z1=[?X1,?Y1], ?Y[?X1->?Y1]}, ?Y:?), ?Z=[?X,?M1]), juergen[?X->?Y] }.

 
results in:
?M = [name->"Jürgen", age->28,
 address->[street->"An der RaumFabrik", ort->"Durlach"]].

 

 

Implementation

Maps are stored as functions internally. The function symbol is $m and the arguments are a sequence of key value pairs. This implies that the key,value pairs are ordered and that a key can have multiple values.

Therefore [a->b,c->d] does not unify with [c->d,a->b]. If you need to unify maps, use the normalize built-in to bring the key/value pairs in a the same order.

 

 

ObjectLogic term

Description

Internal Representation

[]

Empty list (special constant)

[]

[->]

Empty map (special constant)

[->]

[1,2,3]

list

$l(1,$l(2,$l(3,[])))

[1|?Y]

List head / tail

$l(1,?Y)

[a->1,b->2]

Map

$m(a,1,b,2)

[a->{1,2,3},b->[1,2]]

Multi-valued map. Note the difference between the values for a and b. a is multi-valued, but b has a list as value.

$m(a,1,a,2,a,3,b,$l(1,$l(2,[])))