Some advice on a "simple" thing...

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Some advice on a "simple" thing...

emacstheviking
Hello list,

I have almost completed a predicate called ‘jread’ which parses a Java .class file into a term that will allow me to create a database of all of the methods, fields, superclass and interfaces for that class and ultimately create a database for a complete “android.jar” file of any required API level.

I am, for educational purposes and my own learning, trying to build a system like Hoogle/Hayoo for Android. I do a lot of Android and I wanted to create a sytem I can wire into Emacs/IntelliJ or anything for that matter, a simple HTTP server that can supply a list of methods that have a certain type signature using a si mple query language.  Searching by types it very very useful when using Haskell and I wanted to improve my Prolog so I figured why not do something like that in GNU Prolog? I have already started a simple HTTP library in pure GNU Prolog as well but this comes first now.

Progress so far is good…if I run it like this from a folder containing the unpacked android.jar file...

| ?- jread('javax/net/SocketFactory.class',X).

X = javaclass(super('java/lang/Object'),class('javax/net/SocketFactory'),implements([]),
methods([method(access_flags(4),name('<init>'),returns('()V'),[attr(9,
[0,3,0,1,0,0,0,14,42,183,0,1,187,0,2,89,18,3,183,0,4,191,0,0,0,2,0,10,0,0,0,6,0,1,0,0,0
,4,0,11,0,0,0,12,0,1,0,0,0,14,0,12,0,13,0,0])]),method(access_flags(41),name(getDefault)
,returns('()Ljavax/net/SocketFactory;'),attr(9,0,3,0,0,0,0,0,10,187,0,2,89,18,3,183,0,4,
191,0,0,0,1,0,10,0,0,0,6,0,1,0,0,0,5])]),method(access_flags(1),name(createSocket),
returns('()Ljava/net/Socket;'),[attr(9,0,3,0,1,0,0,0,10,187,0,2,89,18,3,183,0,4,191,
0,0,0,2,0,10,0,0,0,6,0,1,0,0,0,6,0,11,0,0,0,12,0,1,0,0,0,10,0,12,0,13,0,0]),
attr(18,0,1,0,19])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/lang/String;I)Ljava/net/Socket;'),[attr(18,[0,2,0,19,0,21])]),
method(access_flags(1025),name(createSocket),
returns('(Ljava/lang/String;ILjava/net/InetAddress;I)Ljava/net/Socket;’),
[attr(18,[0,2,0,19,0,21])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/net/InetAddress;I)Ljava/net/Socket;’),[attr(18[0,1,0,19])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/net/InetAddress;ILjava/net/InetAddress;I)Ljava/net/Socket;'),[attr(18,[0,1,0,19])])])) ? 

The place I am at now is decoding the bit flags for the class (and eventually the methods etc) into a term.

A typical value would be “1057” decimal, 0x421, this contains the flags:

ACC_PUBLIC 0x0001 Declared public; may be accessed from outside its package.
ACC_FINAL 0x0010 Declared final; no subclasses allowed.
ACC_SUPER 0x0020 Treat superclass methods specially when invoked by the invokespecial instruction.
ACC_INTERFACE 0x0200 Is an interface, not a class.
ACC_ABSTRACT 0x0400 Declared abstract; must not be instantiated.
ACC_SYNTHETIC 0x1000 Declared synthetic; not present in the source code.
ACC_ANNOTATION 0x2000 Declared as an annotation type.
ACC_ENUM 0x4000 Declared as an enum type.

So you can see that 0x421 means “ACC_PUBLIC, ACC_SUPER and ACC_ABSTRACT”. I would like to produce a term something like this:

    access_flags(public,super,abstract)

It’s not that I don’t know how to do it or that I can’t do it but I am not sure what is the *most elegant* way to do it in Prolog! Heaven knows I have written bit shifting loops to test for flags in a dozen languages but not in Prolog.

So, there’s the challenge, what is the most elegant way to turn a list of bits into a list of atom terms. Ideally I would make the list of atoms a parameter so that I can reuse it for the other flag based values.

Consider the gauntlet thrown!   In the meantime I am continuing to research the possibilities for myself. I will of course put it all on GitHub along with my Redis client. I may even create a Redis database with the information!

:)
Sean.


_______________________________________________
Users-prolog mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/users-prolog
Reply | Threaded
Open this post in threaded view
|

Re: Some advice on a "simple" thing...

Daniel Diaz-3
Hello Sean,

you can do this with your own loop or use findall like this:

flag(public, 0x0001).
flag(final, 0x0010).
flag(super, 0x0020).
flag(interface, 0x0200).
flag(abstract, 0x0400).
flag(synthetic, 0x1000).
flag(annotation, 0x2000).
flag(enum, 0x4000).


get_java_flags(Value, Flags) :-
    findall(Name, has_flag(Value, Name), Flags).


has_flag(Value, Name) :-
    flag(Name, Mask),
    Value /\ Mask =\= 0.


then call it with:

| ?- get_java_flags(0x421, Flags).

Flags = [public,super,abstract]

I have detailed a bit to be more comprehensive: the has_flag/2 predicate could be inlined inside the findall surrounding with ().

If you prefer to have the flags as a parameter pass them as a list and use member to handle backtracking (done by get_flags/3 here):

get_java_flags(Value, Flags) :-
    FlagNames = [public = 0x0001,
                final = 0x0010,
                super = 0x0020,
                interface = 0x0200,
                abstract = 0x0400,
                synthetic = 0x1000,
                annotation = 0x2000,
                enum = 0x4000],
    get_flags(FlagNames, Value, Flags).



get_flags(FlagNames, Value, Flags) :-
    findall(Name, has_flag(FlagNames, Value, Name), Flags).

has_flag(NameFlags, Value, Name) :-
    member(Name=Mask, NameFlags),
    Value /\ Mask =\= 0.


Daniel

Le 09/04/2014 01:02, Sean Charles a écrit :
Hello list,

I have almost completed a predicate called ‘jread’ which parses a Java .class file into a term that will allow me to create a database of all of the methods, fields, superclass and interfaces for that class and ultimately create a database for a complete “android.jar” file of any required API level.

I am, for educational purposes and my own learning, trying to build a system like Hoogle/Hayoo for Android. I do a lot of Android and I wanted to create a sytem I can wire into Emacs/IntelliJ or anything for that matter, a simple HTTP server that can supply a list of methods that have a certain type signature using a si mple query language.  Searching by types it very very useful when using Haskell and I wanted to improve my Prolog so I figured why not do something like that in GNU Prolog? I have already started a simple HTTP library in pure GNU Prolog as well but this comes first now.

Progress so far is good…if I run it like this from a folder containing the unpacked android.jar file...

| ?- jread('javax/net/SocketFactory.class',X).

X = javaclass(super('java/lang/Object'),class('javax/net/SocketFactory'),implements([]),
methods([method(access_flags(4),name('<init>'),returns('()V'),[attr(9,
[0,3,0,1,0,0,0,14,42,183,0,1,187,0,2,89,18,3,183,0,4,191,0,0,0,2,0,10,0,0,0,6,0,1,0,0,0
,4,0,11,0,0,0,12,0,1,0,0,0,14,0,12,0,13,0,0])]),method(access_flags(41),name(getDefault)
,returns('()Ljavax/net/SocketFactory;'),attr(9,0,3,0,0,0,0,0,10,187,0,2,89,18,3,183,0,4,
191,0,0,0,1,0,10,0,0,0,6,0,1,0,0,0,5])]),method(access_flags(1),name(createSocket),
returns('()Ljava/net/Socket;'),[attr(9,0,3,0,1,0,0,0,10,187,0,2,89,18,3,183,0,4,191,
0,0,0,2,0,10,0,0,0,6,0,1,0,0,0,6,0,11,0,0,0,12,0,1,0,0,0,10,0,12,0,13,0,0]),
attr(18,0,1,0,19])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/lang/String;I)Ljava/net/Socket;'),[attr(18,[0,2,0,19,0,21])]),
method(access_flags(1025),name(createSocket),
returns('(Ljava/lang/String;ILjava/net/InetAddress;I)Ljava/net/Socket;’),
[attr(18,[0,2,0,19,0,21])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/net/InetAddress;I)Ljava/net/Socket;’),[attr(18[0,1,0,19])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/net/InetAddress;ILjava/net/InetAddress;I)Ljava/net/Socket;'),[attr(18,[0,1,0,19])])])) ? 

The place I am at now is decoding the bit flags for the class (and eventually the methods etc) into a term.

A typical value would be “1057” decimal, 0x421, this contains the flags:

ACC_PUBLIC 0x0001 Declared public; may be accessed from outside its package.
ACC_FINAL 0x0010 Declared final; no subclasses allowed.
ACC_SUPER 0x0020 Treat superclass methods specially when invoked by the invokespecial instruction.
ACC_INTERFACE 0x0200 Is an interface, not a class.
ACC_ABSTRACT 0x0400 Declared abstract; must not be instantiated.
ACC_SYNTHETIC 0x1000 Declared synthetic; not present in the source code.
ACC_ANNOTATION 0x2000 Declared as an annotation type.
ACC_ENUM 0x4000 Declared as an enum type.

So you can see that 0x421 means “ACC_PUBLIC, ACC_SUPER and ACC_ABSTRACT”. I would like to produce a term something like this:

    access_flags(public,super,abstract)

It’s not that I don’t know how to do it or that I can’t do it but I am not sure what is the *most elegant* way to do it in Prolog! Heaven knows I have written bit shifting loops to test for flags in a dozen languages but not in Prolog.

So, there’s the challenge, what is the most elegant way to turn a list of bits into a list of atom terms. Ideally I would make the list of atoms a parameter so that I can reuse it for the other flag based values.

Consider the gauntlet thrown!   In the meantime I am continuing to research the possibilities for myself. I will of course put it all on GitHub along with my Redis client. I may even create a Redis database with the information!

:)
Sean.




--
Ce message a été vérifié par MailScanner pour des virus ou des polluriels et rien de suspect n'a été trouvé.
_______________________________________________
Users-prolog mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/users-prolog
Reply | Threaded
Open this post in threaded view
|

Re: Some advice on a "simple" thing...

emacstheviking
Some clarificaation…. a while back you helped me write a testing framework…here is the code:
get_all_tests(Tests) :-
setof(Line-Name, get_one_test(Name, Line), Tests).


get_one_test(Name, Line) :-
current_predicate(Name/0),
atom_concat('test_', _, Name),
predicate_property(Name, prolog_line(Line)).
It uses ‘pairs’ as I understand them, using the ‘-‘ to combine the key and value, so in your response, what is ‘=‘ doing in this context in the list of flags????

Just when I thouthgh I was beginning to understand! LMAO

Thanks once again,

Sean.




On 9 Apr 2014, at 09:18, Daniel Diaz <[hidden email]> wrote:

Hello Sean,

you can do this with your own loop or use findall like this:

flag(public, 0x0001).
flag(final, 0x0010).
flag(super, 0x0020).
flag(interface, 0x0200).
flag(abstract, 0x0400).
flag(synthetic, 0x1000).
flag(annotation, 0x2000).
flag(enum, 0x4000).


get_java_flags(Value, Flags) :-
    findall(Name, has_flag(Value, Name), Flags).


has_flag(Value, Name) :-
    flag(Name, Mask),
    Value /\ Mask =\= 0.


then call it with:

| ?- get_java_flags(0x421, Flags).

Flags = [public,super,abstract]

I have detailed a bit to be more comprehensive: the has_flag/2 predicate could be inlined inside the findall surrounding with ().

If you prefer to have the flags as a parameter pass them as a list and use member to handle backtracking (done by get_flags/3 here):

get_java_flags(Value, Flags) :-
    FlagNames = [public = 0x0001,
                final = 0x0010,
                super = 0x0020,
                interface = 0x0200,
                abstract = 0x0400,
                synthetic = 0x1000,
                annotation = 0x2000,
                enum = 0x4000],
    get_flags(FlagNames, Value, Flags).



get_flags(FlagNames, Value, Flags) :-
    findall(Name, has_flag(FlagNames, Value, Name), Flags).

has_flag(NameFlags, Value, Name) :-
    member(Name=Mask, NameFlags),
    Value /\ Mask =\= 0.


Daniel

Le 09/04/2014 01:02, Sean Charles a écrit :
Hello list,

I have almost completed a predicate called ‘jread’ which parses a Java .class file into a term that will allow me to create a database of all of the methods, fields, superclass and interfaces for that class and ultimately create a database for a complete “android.jar” file of any required API level.

I am, for educational purposes and my own learning, trying to build a system like Hoogle/Hayoo for Android. I do a lot of Android and I wanted to create a sytem I can wire into Emacs/IntelliJ or anything for that matter, a simple HTTP server that can supply a list of methods that have a certain type signature using a si mple query language.  Searching by types it very very useful when using Haskell and I wanted to improve my Prolog so I figured why not do something like that in GNU Prolog? I have already started a simple HTTP library in pure GNU Prolog as well but this comes first now.

Progress so far is good…if I run it like this from a folder containing the unpacked android.jar file...

| ?- jread('javax/net/SocketFactory.class',X).

X = javaclass(super('java/lang/Object'),class('javax/net/SocketFactory'),implements([]),
methods([method(access_flags(4),name('<init>'),returns('()V'),[attr(9,
[0,3,0,1,0,0,0,14,42,183,0,1,187,0,2,89,18,3,183,0,4,191,0,0,0,2,0,10,0,0,0,6,0,1,0,0,0
,4,0,11,0,0,0,12,0,1,0,0,0,14,0,12,0,13,0,0])]),method(access_flags(41),name(getDefault)
,returns('()Ljavax/net/SocketFactory;'),attr(9,0,3,0,0,0,0,0,10,187,0,2,89,18,3,183,0,4,
191,0,0,0,1,0,10,0,0,0,6,0,1,0,0,0,5])]),method(access_flags(1),name(createSocket),
returns('()Ljava/net/Socket;'),[attr(9,0,3,0,1,0,0,0,10,187,0,2,89,18,3,183,0,4,191,
0,0,0,2,0,10,0,0,0,6,0,1,0,0,0,6,0,11,0,0,0,12,0,1,0,0,0,10,0,12,0,13,0,0]),
attr(18,0,1,0,19])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/lang/String;I)Ljava/net/Socket;'),[attr(18,[0,2,0,19,0,21])]),
method(access_flags(1025),name(createSocket),
returns('(Ljava/lang/String;ILjava/net/InetAddress;I)Ljava/net/Socket;’),
[attr(18,[0,2,0,19,0,21])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/net/InetAddress;I)Ljava/net/Socket;’),[attr(18[0,1,0,19])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/net/InetAddress;ILjava/net/InetAddress;I)Ljava/net/Socket;'),[attr(18,[0,1,0,19])])])) ? 

The place I am at now is decoding the bit flags for the class (and eventually the methods etc) into a term.

A typical value would be “1057” decimal, 0x421, this contains the flags:

ACC_PUBLIC 0x0001 Declared public; may be accessed from outside its package.
ACC_FINAL 0x0010 Declared final; no subclasses allowed.
ACC_SUPER 0x0020 Treat superclass methods specially when invoked by the invokespecial instruction.
ACC_INTERFACE 0x0200 Is an interface, not a class.
ACC_ABSTRACT 0x0400 Declared abstract; must not be instantiated.
ACC_SYNTHETIC 0x1000 Declared synthetic; not present in the source code.
ACC_ANNOTATION 0x2000 Declared as an annotation type.
ACC_ENUM 0x4000 Declared as an enum type.

So you can see that 0x421 means “ACC_PUBLIC, ACC_SUPER and ACC_ABSTRACT”. I would like to produce a term something like this:

    access_flags(public,super,abstract)

It’s not that I don’t know how to do it or that I can’t do it but I am not sure what is the *most elegant* way to do it in Prolog! Heaven knows I have written bit shifting loops to test for flags in a dozen languages but not in Prolog.

So, there’s the challenge, what is the most elegant way to turn a list of bits into a list of atom terms. Ideally I would make the list of atoms a parameter so that I can reuse it for the other flag based values.

Consider the gauntlet thrown!   In the meantime I am continuing to research the possibilities for myself. I will of course put it all on GitHub along with my Redis client. I may even create a Redis database with the information!

:)
Sean.




--
Ce message a été vérifié par MailScanner pour des virus ou des polluriels et rien de suspect n'a été trouvé.


_______________________________________________
Users-prolog mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/users-prolog
Reply | Threaded
Open this post in threaded view
|

Re: Some advice on a "simple" thing...

Daniel Diaz-3
Le 09/04/2014 15:07, Sean Charles a écrit :
Some clarificaation…. a while back you helped me write a testing framework…here is the code:
get_all_tests(Tests) :-
setof(Line-Name, get_one_test(Name, Line), Tests).
get_one_test(Name, Line) :-
current_predicate(Name/0),
atom_concat('test_', _, Name),
predicate_property(Name, prolog_line(Line)).
It uses ‘pairs’ as I understand them, using the ‘-‘ to combine the key and value, so in your response, what is ‘=‘ doing in this context in the list of flags????

There is no special meaning for '-' (except keysort/2 which sorts a list of pairs of the form Key-Value according to the Keys). In the above code
I used a functor - but a = would work as well. We only need a structure to group 2 values (the functor does not care in this case).

Daniel

Just when I thouthgh I was beginning to understand! LMAO

Thanks once again,

Sean.




On 9 Apr 2014, at 09:18, Daniel Diaz <[hidden email]> wrote:

Hello Sean,

you can do this with your own loop or use findall like this:

flag(public, 0x0001).
flag(final, 0x0010).
flag(super, 0x0020).
flag(interface, 0x0200).
flag(abstract, 0x0400).
flag(synthetic, 0x1000).
flag(annotation, 0x2000).
flag(enum, 0x4000).


get_java_flags(Value, Flags) :-
    findall(Name, has_flag(Value, Name), Flags).


has_flag(Value, Name) :-
    flag(Name, Mask),
    Value /\ Mask =\= 0.


then call it with:

| ?- get_java_flags(0x421, Flags).

Flags = [public,super,abstract]

I have detailed a bit to be more comprehensive: the has_flag/2 predicate could be inlined inside the findall surrounding with ().

If you prefer to have the flags as a parameter pass them as a list and use member to handle backtracking (done by get_flags/3 here):

get_java_flags(Value, Flags) :-
    FlagNames = [public = 0x0001,
                final = 0x0010,
                super = 0x0020,
                interface = 0x0200,
                abstract = 0x0400,
                synthetic = 0x1000,
                annotation = 0x2000,
                enum = 0x4000],
    get_flags(FlagNames, Value, Flags).



get_flags(FlagNames, Value, Flags) :-
    findall(Name, has_flag(FlagNames, Value, Name), Flags).

has_flag(NameFlags, Value, Name) :-
    member(Name=Mask, NameFlags),
    Value /\ Mask =\= 0.


Daniel

Le 09/04/2014 01:02, Sean Charles a écrit :
Hello list,

I have almost completed a predicate called ‘jread’ which parses a Java .class file into a term that will allow me to create a database of all of the methods, fields, superclass and interfaces for that class and ultimately create a database for a complete “android.jar” file of any required API level.

I am, for educational purposes and my own learning, trying to build a system like Hoogle/Hayoo for Android. I do a lot of Android and I wanted to create a sytem I can wire into Emacs/IntelliJ or anything for that matter, a simple HTTP server that can supply a list of methods that have a certain type signature using a si mple query language.  Searching by types it very very useful when using Haskell and I wanted to improve my Prolog so I figured why not do something like that in GNU Prolog? I have already started a simple HTTP library in pure GNU Prolog as well but this comes first now.

Progress so far is good…if I run it like this from a folder containing the unpacked android.jar file...

| ?- jread('javax/net/SocketFactory.class',X).

X = javaclass(super('java/lang/Object'),class('javax/net/SocketFactory'),implements([]),
methods([method(access_flags(4),name('<init>'),returns('()V'),[attr(9,
[0,3,0,1,0,0,0,14,42,183,0,1,187,0,2,89,18,3,183,0,4,191,0,0,0,2,0,10,0,0,0,6,0,1,0,0,0
,4,0,11,0,0,0,12,0,1,0,0,0,14,0,12,0,13,0,0])]),method(access_flags(41),name(getDefault)
,returns('()Ljavax/net/SocketFactory;'),attr(9,0,3,0,0,0,0,0,10,187,0,2,89,18,3,183,0,4,
191,0,0,0,1,0,10,0,0,0,6,0,1,0,0,0,5])]),method(access_flags(1),name(createSocket),
returns('()Ljava/net/Socket;'),[attr(9,0,3,0,1,0,0,0,10,187,0,2,89,18,3,183,0,4,191,
0,0,0,2,0,10,0,0,0,6,0,1,0,0,0,6,0,11,0,0,0,12,0,1,0,0,0,10,0,12,0,13,0,0]),
attr(18,0,1,0,19])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/lang/String;I)Ljava/net/Socket;'),[attr(18,[0,2,0,19,0,21])]),
method(access_flags(1025),name(createSocket),
returns('(Ljava/lang/String;ILjava/net/InetAddress;I)Ljava/net/Socket;’),
[attr(18,[0,2,0,19,0,21])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/net/InetAddress;I)Ljava/net/Socket;’),[attr(18[0,1,0,19])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/net/InetAddress;ILjava/net/InetAddress;I)Ljava/net/Socket;'),[attr(18,[0,1,0,19])])])) ? 

The place I am at now is decoding the bit flags for the class (and eventually the methods etc) into a term.

A typical value would be “1057” decimal, 0x421, this contains the flags:

ACC_PUBLIC 0x0001 Declared public; may be accessed from outside its package.
ACC_FINAL 0x0010 Declared final; no subclasses allowed.
ACC_SUPER 0x0020 Treat superclass methods specially when invoked by the invokespecial instruction.
ACC_INTERFACE 0x0200 Is an interface, not a class.
ACC_ABSTRACT 0x0400 Declared abstract; must not be instantiated.
ACC_SYNTHETIC 0x1000 Declared synthetic; not present in the source code.
ACC_ANNOTATION 0x2000 Declared as an annotation type.
ACC_ENUM 0x4000 Declared as an enum type.

So you can see that 0x421 means “ACC_PUBLIC, ACC_SUPER and ACC_ABSTRACT”. I would like to produce a term something like this:

    access_flags(public,super,abstract)

It’s not that I don’t know how to do it or that I can’t do it but I am not sure what is the *most elegant* way to do it in Prolog! Heaven knows I have written bit shifting loops to test for flags in a dozen languages but not in Prolog.

So, there’s the challenge, what is the most elegant way to turn a list of bits into a list of atom terms. Ideally I would make the list of atoms a parameter so that I can reuse it for the other flag based values.

Consider the gauntlet thrown!   In the meantime I am continuing to research the possibilities for myself. I will of course put it all on GitHub along with my Redis client. I may even create a Redis database with the information!

:)
Sean.




--
Ce message a été vérifié par MailScanner pour des virus ou des polluriels et rien de suspect n'a été trouvé.
_______________________________________________
Users-prolog mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/users-prolog
Reply | Threaded
Open this post in threaded view
|

Re: Some advice on a "simple" thing...

emacstheviking
Wow, I didn't realise how little I understood!

I am *guessing* now that by writing A=B in the list is the same as =(A,B) and so in the code:

has_flag(NameFlags, Value, Name) :-
    member(Name=Mask, NameFlags),
    Value /\ Mask =\= 0.

It could be rewritten as:

has_flag(NameFlags, Value, Name) :-
    member(=(Name, Mask), NameFlags),
    Value /\ Mask =\= 0.

at which point my brain goes, "Aha! It is *just* unification after all and not magic".

Is that a correct intrepretation?  And why '=', is it the case that any functor would have done, for example could I have as easily written this:

has_flag(NameFlags, Value, Name) :-
    member(foo(Name,Mask), NameFlags),
    Value /\ Mask =\= 0.

and this:

has_flag(NameFlags, Value, Name) :-
    member(foo(Name, Mask), NameFlags),
    Value /\ Mask =\= 0.

Did you use '=' because it is builtin?? I am guessing I could use op() to define my own, I will just for the hell of it and learn some more. (I *will* try this but I am in work right now so I can't!) I think tonight I advance my Prolog skills a little more. I will read LPN! on line about functors. II left my Prolog books home this week!

Thanks once again for your time.

Sean.



On 9 April 2014 17:03, Daniel Diaz <[hidden email]> wrote:
Le 09/04/2014 15:07, Sean Charles a écrit :
Some clarificaation…. a while back you helped me write a testing framework…here is the code:
get_all_tests(Tests) :-
setof(Line-Name, get_one_test(Name, Line), Tests).
get_one_test(Name, Line) :-
current_predicate(Name/0),
atom_concat('test_', _, Name),
predicate_property(Name, prolog_line(Line)).
It uses ‘pairs’ as I understand them, using the ‘-‘ to combine the key and value, so in your response, what is ‘=‘ doing in this context in the list of flags????

There is no special meaning for '-' (except keysort/2 which sorts a list of pairs of the form Key-Value according to the Keys). In the above code
I used a functor - but a = would work as well. We only need a structure to group 2 values (the functor does not care in this case).

Daniel


Just when I thouthgh I was beginning to understand! LMAO

Thanks once again,

Sean.




On 9 Apr 2014, at 09:18, Daniel Diaz <[hidden email]> wrote:

Hello Sean,

you can do this with your own loop or use findall like this:

flag(public, 0x0001).
flag(final, 0x0010).
flag(super, 0x0020).
flag(interface, 0x0200).
flag(abstract, 0x0400).
flag(synthetic, 0x1000).
flag(annotation, 0x2000).
flag(enum, 0x4000).


get_java_flags(Value, Flags) :-
    findall(Name, has_flag(Value, Name), Flags).


has_flag(Value, Name) :-
    flag(Name, Mask),
    Value /\ Mask =\= 0.


then call it with:

| ?- get_java_flags(0x421, Flags).

Flags = [public,super,abstract]

I have detailed a bit to be more comprehensive: the has_flag/2 predicate could be inlined inside the findall surrounding with ().

If you prefer to have the flags as a parameter pass them as a list and use member to handle backtracking (done by get_flags/3 here):

get_java_flags(Value, Flags) :-
    FlagNames = [public = 0x0001,
                final = 0x0010,
                super = 0x0020,
                interface = 0x0200,
                abstract = 0x0400,
                synthetic = 0x1000,
                annotation = 0x2000,
                enum = 0x4000],
    get_flags(FlagNames, Value, Flags).



get_flags(FlagNames, Value, Flags) :-
    findall(Name, has_flag(FlagNames, Value, Name), Flags).

has_flag(NameFlags, Value, Name) :-
    member(Name=Mask, NameFlags),
    Value /\ Mask =\= 0.


Daniel

Le 09/04/2014 01:02, Sean Charles a écrit :
Hello list,

I have almost completed a predicate called ‘jread’ which parses a Java .class file into a term that will allow me to create a database of all of the methods, fields, superclass and interfaces for that class and ultimately create a database for a complete “android.jar” file of any required API level.

I am, for educational purposes and my own learning, trying to build a system like Hoogle/Hayoo for Android. I do a lot of Android and I wanted to create a sytem I can wire into Emacs/IntelliJ or anything for that matter, a simple HTTP server that can supply a list of methods that have a certain type signature using a si mple query language.  Searching by types it very very useful when using Haskell and I wanted to improve my Prolog so I figured why not do something like that in GNU Prolog? I have already started a simple HTTP library in pure GNU Prolog as well but this comes first now.

Progress so far is good…if I run it like this from a folder containing the unpacked android.jar file...

| ?- jread('javax/net/SocketFactory.class',X).

X = javaclass(super('java/lang/Object'),class('javax/net/SocketFactory'),implements([]),
methods([method(access_flags(4),name('<init>'),returns('()V'),[attr(9,
[0,3,0,1,0,0,0,14,42,183,0,1,187,0,2,89,18,3,183,0,4,191,0,0,0,2,0,10,0,0,0,6,0,1,0,0,0
,4,0,11,0,0,0,12,0,1,0,0,0,14,0,12,0,13,0,0])]),method(access_flags(41),name(getDefault)
,returns('()Ljavax/net/SocketFactory;'),attr(9,0,3,0,0,0,0,0,10,187,0,2,89,18,3,183,0,4,
191,0,0,0,1,0,10,0,0,0,6,0,1,0,0,0,5])]),method(access_flags(1),name(createSocket),
returns('()Ljava/net/Socket;'),[attr(9,0,3,0,1,0,0,0,10,187,0,2,89,18,3,183,0,4,191,
0,0,0,2,0,10,0,0,0,6,0,1,0,0,0,6,0,11,0,0,0,12,0,1,0,0,0,10,0,12,0,13,0,0]),
attr(18,0,1,0,19])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/lang/String;I)Ljava/net/Socket;'),[attr(18,[0,2,0,19,0,21])]),
method(access_flags(1025),name(createSocket),
returns('(Ljava/lang/String;ILjava/net/InetAddress;I)Ljava/net/Socket;’),
[attr(18,[0,2,0,19,0,21])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/net/InetAddress;I)Ljava/net/Socket;’),[attr(18[0,1,0,19])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/net/InetAddress;ILjava/net/InetAddress;I)Ljava/net/Socket;'),[attr(18,[0,1,0,19])])])) ? 

The place I am at now is decoding the bit flags for the class (and eventually the methods etc) into a term.

A typical value would be “1057” decimal, 0x421, this contains the flags:

ACC_PUBLIC 0x0001 Declared public; may be accessed from outside its package.
ACC_FINAL 0x0010 Declared final; no subclasses allowed.
ACC_SUPER 0x0020 Treat superclass methods specially when invoked by the invokespecial instruction.
ACC_INTERFACE 0x0200 Is an interface, not a class.
ACC_ABSTRACT 0x0400 Declared abstract; must not be instantiated.
ACC_SYNTHETIC 0x1000 Declared synthetic; not present in the source code.
ACC_ANNOTATION 0x2000 Declared as an annotation type.
ACC_ENUM 0x4000 Declared as an enum type.

So you can see that 0x421 means “ACC_PUBLIC, ACC_SUPER and ACC_ABSTRACT”. I would like to produce a term something like this:

    access_flags(public,super,abstract)

It’s not that I don’t know how to do it or that I can’t do it but I am not sure what is the *most elegant* way to do it in Prolog! Heaven knows I have written bit shifting loops to test for flags in a dozen languages but not in Prolog.

So, there’s the challenge, what is the most elegant way to turn a list of bits into a list of atom terms. Ideally I would make the list of atoms a parameter so that I can reuse it for the other flag based values.

Consider the gauntlet thrown!   In the meantime I am continuing to research the possibilities for myself. I will of course put it all on GitHub along with my Redis client. I may even create a Redis database with the information!

:)
Sean.




--
Ce message a été vérifié par MailScanner pour des virus ou des polluriels et rien de suspect n'a été trouvé.


_______________________________________________
Users-prolog mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/users-prolog
Reply | Threaded
Open this post in threaded view
|

Re: Some advice on a "simple" thing...

Lindsey Spratt-2
In reply to this post by emacstheviking
One of the cool things about Edinborough syntax Prolog is the use of 'operators' - they are just syntactic sugar for function terms. (Cambridge syntax prolog looks like Lisp - I don't think any implementations still exist that use this syntax.)
foo(a - b, c + d, e = f) is semantically equivalent to
foo(-(a, b), +(c, d), =(e,f))
'-(a,b)' does not have a particular interpretation in Prolog, it's meaning is determined (in this case) by what 'foo' does with it and what other clauses referencing 'foo' do with it.

Even the 'neck' operator and 'and' operators of clauses are just syntactic sugar:

foo(X) :- bar(X), baz(X).
is equivalent to
:-(foo(X), ,(bar(X), baz(X))).

(This shows the unfortunate overloading of the comma token as both an operator used for 'and' in clauses and as a term separator.)

This is how arithmetic operations are defined using the 'is' builtin. The 'is' builtin gets a nested function term that uses functors that it interprets as arithmetic operations:
X is 3 + 4 *  2 * 7.
is the same as
X is +(3, *(4, *(2, 7))).
The 'is' builtin applies common arithmetic processing to this nested structure to unify a numeric value 59 with X.

Outside of 'is' and some special comparison builtins, the functors that look like arithmetic operators have no particular semantics:
Y = 3 + 4 * 2 * 7,
(Z + W) = Y.
binds Z to '3' and W to '4 * 2 * 7'. There is no arithmetic processing done in this case.

Programmers are free to use whatever operator makes sense in the context of a particular program to identify pairs of values.

And if none of the pre-defined operators ('-', '+', '=', etc) are appropriate, you can always define your own:
:- op(&=&>, xfy, 500).
:- op(<++, yfx, 250).
for
foo(a &=&> b, c <++ d, e = f).
is the same as
foo(&=&>(a, b), <++(c, d), =(e, f)).

This is great fun for designing domain-specific languages in Prolog.

Lindsey Spratt

On Apr 9, 2014, at 9:07 AM, Sean Charles <[hidden email]> wrote:

Some clarificaation…. a while back you helped me write a testing framework…here is the code:
get_all_tests(Tests) :-
setof(Line-Name, get_one_test(Name, Line), Tests).


get_one_test(Name, Line) :-
current_predicate(Name/0),
atom_concat('test_', _, Name),
predicate_property(Name, prolog_line(Line)).
It uses ‘pairs’ as I understand them, using the ‘-‘ to combine the key and value, so in your response, what is ‘=‘ doing in this context in the list of flags????

Just when I thouthgh I was beginning to understand! LMAO

Thanks once again,

Sean.




On 9 Apr 2014, at 09:18, Daniel Diaz <[hidden email]> wrote:

Hello Sean,

you can do this with your own loop or use findall like this:

flag(public, 0x0001).
flag(final, 0x0010).
flag(super, 0x0020).
flag(interface, 0x0200).
flag(abstract, 0x0400).
flag(synthetic, 0x1000).
flag(annotation, 0x2000).
flag(enum, 0x4000).


get_java_flags(Value, Flags) :-
    findall(Name, has_flag(Value, Name), Flags).


has_flag(Value, Name) :-
    flag(Name, Mask),
    Value /\ Mask =\= 0.


then call it with:

| ?- get_java_flags(0x421, Flags).

Flags = [public,super,abstract]

I have detailed a bit to be more comprehensive: the has_flag/2 predicate could be inlined inside the findall surrounding with ().

If you prefer to have the flags as a parameter pass them as a list and use member to handle backtracking (done by get_flags/3 here):

get_java_flags(Value, Flags) :-
    FlagNames = [public = 0x0001,
                final = 0x0010,
                super = 0x0020,
                interface = 0x0200,
                abstract = 0x0400,
                synthetic = 0x1000,
                annotation = 0x2000,
                enum = 0x4000],
    get_flags(FlagNames, Value, Flags).



get_flags(FlagNames, Value, Flags) :-
    findall(Name, has_flag(FlagNames, Value, Name), Flags).

has_flag(NameFlags, Value, Name) :-
    member(Name=Mask, NameFlags),
    Value /\ Mask =\= 0.


Daniel

Le 09/04/2014 01:02, Sean Charles a écrit :
Hello list,

I have almost completed a predicate called ‘jread’ which parses a Java .class file into a term that will allow me to create a database of all of the methods, fields, superclass and interfaces for that class and ultimately create a database for a complete “android.jar” file of any required API level.

I am, for educational purposes and my own learning, trying to build a system like Hoogle/Hayoo for Android. I do a lot of Android and I wanted to create a sytem I can wire into Emacs/IntelliJ or anything for that matter, a simple HTTP server that can supply a list of methods that have a certain type signature using a si mple query language.  Searching by types it very very useful when using Haskell and I wanted to improve my Prolog so I figured why not do something like that in GNU Prolog? I have already started a simple HTTP library in pure GNU Prolog as well but this comes first now.

Progress so far is good…if I run it like this from a folder containing the unpacked android.jar file...

| ?- jread('javax/net/SocketFactory.class',X).

X = javaclass(super('java/lang/Object'),class('javax/net/SocketFactory'),implements([]),
methods([method(access_flags(4),name('<init>'),returns('()V'),[attr(9,
[0,3,0,1,0,0,0,14,42,183,0,1,187,0,2,89,18,3,183,0,4,191,0,0,0,2,0,10,0,0,0,6,0,1,0,0,0
,4,0,11,0,0,0,12,0,1,0,0,0,14,0,12,0,13,0,0])]),method(access_flags(41),name(getDefault)
,returns('()Ljavax/net/SocketFactory;'),attr(9,0,3,0,0,0,0,0,10,187,0,2,89,18,3,183,0,4,
191,0,0,0,1,0,10,0,0,0,6,0,1,0,0,0,5])]),method(access_flags(1),name(createSocket),
returns('()Ljava/net/Socket;'),[attr(9,0,3,0,1,0,0,0,10,187,0,2,89,18,3,183,0,4,191,
0,0,0,2,0,10,0,0,0,6,0,1,0,0,0,6,0,11,0,0,0,12,0,1,0,0,0,10,0,12,0,13,0,0]),
attr(18,0,1,0,19])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/lang/String;I)Ljava/net/Socket;'),[attr(18,[0,2,0,19,0,21])]),
method(access_flags(1025),name(createSocket),
returns('(Ljava/lang/String;ILjava/net/InetAddress;I)Ljava/net/Socket;’),
[attr(18,[0,2,0,19,0,21])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/net/InetAddress;I)Ljava/net/Socket;’),[attr(18[0,1,0,19])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/net/InetAddress;ILjava/net/InetAddress;I)Ljava/net/Socket;'),[attr(18,[0,1,0,19])])])) ? 

The place I am at now is decoding the bit flags for the class (and eventually the methods etc) into a term.

A typical value would be “1057” decimal, 0x421, this contains the flags:

ACC_PUBLIC 0x0001 Declared public; may be accessed from outside its package.
ACC_FINAL 0x0010 Declared final; no subclasses allowed.
ACC_SUPER 0x0020 Treat superclass methods specially when invoked by the invokespecial instruction.
ACC_INTERFACE 0x0200 Is an interface, not a class.
ACC_ABSTRACT 0x0400 Declared abstract; must not be instantiated.
ACC_SYNTHETIC 0x1000 Declared synthetic; not present in the source code.
ACC_ANNOTATION 0x2000 Declared as an annotation type.
ACC_ENUM 0x4000 Declared as an enum type.

So you can see that 0x421 means “ACC_PUBLIC, ACC_SUPER and ACC_ABSTRACT”. I would like to produce a term something like this:

    access_flags(public,super,abstract)

It’s not that I don’t know how to do it or that I can’t do it but I am not sure what is the *most elegant* way to do it in Prolog! Heaven knows I have written bit shifting loops to test for flags in a dozen languages but not in Prolog.

So, there’s the challenge, what is the most elegant way to turn a list of bits into a list of atom terms. Ideally I would make the list of atoms a parameter so that I can reuse it for the other flag based values.

Consider the gauntlet thrown!   In the meantime I am continuing to research the possibilities for myself. I will of course put it all on GitHub along with my Redis client. I may even create a Redis database with the information!

:)
Sean.




--
Ce message a été vérifié par MailScanner pour des virus ou des polluriels et rien de suspect n'a été trouvé.

_______________________________________________
Users-prolog mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/users-prolog


_______________________________________________
Users-prolog mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/users-prolog
Reply | Threaded
Open this post in threaded view
|

Re: Some advice on a "simple" thing...

emacstheviking


> One of the cool things about Edinborough syntax Prolog is the use of 'operators' - they are just syntactic sugar for function terms. (Cambridge syntax prolog looks like Lisp - I don't think any implementations still exist that use this syntax.)

Is that the syntax used in Art of Prolog? I recognise it from there I am sure.

> foo(a - b, c + d, e = f) is semantically equivalent to
> foo(-(a, b), +(c, d), =(e,f))
> '-(a,b)' does not have a particular interpretation in Prolog, it's meaning is determined (in this case) by what 'foo' does with it and what other clauses referencing 'foo' do with it.

OK, so the “traditional” operators are defined but they are given no special meaning unless used with “is”. Correct??

>
> This is how arithmetic operations are defined using the 'is' builtin. The 'is' builtin gets a nested function term that uses functors that it interprets as arithmetic operations:
> X is 3 + 4 *  2 * 7.
> is the same as
> X is +(3, *(4, *(2, 7))).
> The 'is' builtin applies common arithmetic processing to this nested structure to unify a numeric value 59 with X.

Within the context of “is”, does the functor know what it has to do with its arguments or is it the “is” processing code the decides to add, subtract etc. ? I guess that’s an implementation detail and would vary between vendors.

>
> Outside of 'is' and some special comparison builtins, the functors that look like arithmetic operators have no particular semantics:
> Y = 3 + 4 * 2 * 7,
> (Z + W) = Y.
> binds Z to '3' and W to '4 * 2 * 7'. There is no arithmetic processing done in this case.

That I understand BUT how does the unification engine know to pattern match….hang on, a light is starting to come on now… by rewriting the expression as:

   Y = +(3, +(4, *(2, 7))),
    +(Z, Y) = Y.

I can now see that unification will match Z to 3 and Y to the remainder. YES!!!! HAHAHA Eureka.   I remember making myself write stuff out in Haskell and not using the >> operator until I “got it”, this feels the same. Excellent!! (Good job ! is free to type).

Lindsey and Daniel, thankyou very much for your replies. I have taken another step forward!  This is sometimes the downside of not having “done CS at school” and had the supreme luxury of all the hours in the day to learn and reflect. Great. This is truly great, well, for me it is, I am sure plenty of readers are thinking, “Well like yeah, I thought everybody knew that from CS101”.

Thanks!  :) Now I can begin world domination with GNU Prolog….

Sean.


_______________________________________________
Users-prolog mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/users-prolog
Reply | Threaded
Open this post in threaded view
|

Re: Some advice on a "simple" thing...

Daniel Diaz-3
Hi Sean and Lindsey,

some more explanations... In case of...

Le 09/04/2014 22:44, Sean Charles a écrit :
>> foo(a - b, c + d, e = f) is semantically equivalent to
>> foo(-(a, b), +(c, d), =(e,f))
>> '-(a,b)' does not have a particular interpretation in Prolog, it's meaning is determined (in this case) by what 'foo' does with it and what other clauses referencing 'foo' do with it.
> OK, so the “traditional” operators are defined but they are given no special meaning unless used with “is”. Correct??

As Lindsey explained, operator notation is just syntactic sugar.
Internally you just have compound terms (structures) composed of : 1
functor (must be an atom) and N arguments which are Prolog terms (N is
called the arity). For instance foo(zoe,1) is a structure of arity 2
whose functor is the atom foo and the 2 arguments are zoe and 1. We use
the notation foo/2 to speak about a structure independently of the
arguments.

Operators can be defined (some are predefined) to ease the interaction
with the user (and to make programs more readable). So operators are
only used with I/O. When an operator is defined, by default the operator
notation is used when the term is written. But you can use the display
built-in to prevent this notation. Examples:

| ?- write(foo(zoe,1)).
foo(zoe,1)

yes
| ?- write(=(zoe,1)).
zoe=1

yes
| ?- display(=(zoe,1)).
=(zoe,1)

yes

You can also use the operator notation as input (as you can see the
results are similar to above):

| ?- write(zoe=1).
zoe=1

yes
| ?- display(zoe=1).
=(zoe,1)

You can also define your own operator:

| ?- op(400,xfx,foo).

yes
| ?- write(foo(zoe,1)).
zoe foo 1

yes
| ?- display(foo(zoe,1)).
foo(zoe,1)

yes



>> This is how arithmetic operations are defined using the 'is' builtin. The 'is' builtin gets a nested function term that uses functors that it interprets as arithmetic operations:
>> X is 3 + 4 *  2 * 7.
>> is the same as
>> X is +(3, *(4, *(2, 7))).
>> The 'is' builtin applies common arithmetic processing to this nested structure to unify a numeric value 59 with X.
> Within the context of “is”, does the functor know what it has to do with its arguments or is it the “is” processing code the decides to add, subtract etc. ? I guess that’s an implementation detail and would vary between vendors.
NB: Prolog uses a unified syntax both for the programs (ie. the
predicates) and the data (arguments of the predicates). This is nice for
meta-programming (Prolog programs handling as data other Prolog
programs). In the case of

X is 3 + 4 *  2 * 7.

which is the same as

X is +(3, *(4, *(2, 7))).

It is also the same as:

is(X, +(3, *(4, *(2, 7)))).

| ?- is(X, +(3, *(4, *(2, 7)))).

X = 59

You can now see that the predicate you invoke is called is/2. This is a
mathematical predicate which evaluates its second argument (an
expression given as a Prolog term) and unifies the result with its first
argument.

Daniel

--
Ce message a ete verifie par MailScanner
pour des virus ou des polluriels et rien de
suspect n'a ete trouve.


_______________________________________________
Users-prolog mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/users-prolog
Reply | Threaded
Open this post in threaded view
|

Re: Some advice on a "simple" thing...

emacstheviking
Just to close this off for me personally, am I correct iin my understanding that a term such as this:

something( 100, arg(int,100), string(c_style, "Hello")).

has a "primary" (principle?!) functor of something/3 and that the arguments are JUST terms i.e. they arg/2 and string/2 are not evaluated they are just lxed,parsed and stored as Prolog terms and that if I wanted to actually have them execute during the course being processed that I would have to use call/1 to make that happen.

That's how I understand it. It is a bit like quoting a list in Lisp, the list is not executed but stored as is.

If that is correct, I feel much better about how I understand Prolog. Somtimes I can't beleive I actually wrote that Redis collection but it just goes to show that you only need to know and understand "just enough" to actually amke something work but for me the real enjoyment is pushing your understanding down into eveyr nook and cranny of a language!

Thanks again,
Sean.



On 10 April 2014 08:26, Daniel Diaz <[hidden email]> wrote:
Hi Sean and Lindsey,

some more explanations... In case of...

Le 09/04/2014 22:44, Sean Charles a écrit :

        foo(a - b, c + d, e = f) is semantically equivalent to
        foo(-(a, b), +(c, d), =(e,f))
'-(a,b)' does not have a particular interpretation in Prolog, it's meaning is determined (in this case) by what 'foo' does with it and what other clauses referencing 'foo' do with it.
OK, so the “traditional” operators are defined but they are given no special meaning unless used with “is”. Correct??

As Lindsey explained, operator notation is just syntactic sugar. Internally you just have compound terms (structures) composed of : 1 functor (must be an atom) and N arguments which are Prolog terms (N is called the arity). For instance foo(zoe,1) is a structure of arity 2 whose functor is the atom foo and the 2 arguments are zoe and 1. We use the notation foo/2 to speak about a structure independently of the arguments.

Operators can be defined (some are predefined) to ease the interaction with the user (and to make programs more readable). So operators are only used with I/O. When an operator is defined, by default the operator notation is used when the term is written. But you can use the display built-in to prevent this notation. Examples:

| ?- write(foo(zoe,1)).
foo(zoe,1)

yes
| ?- write(=(zoe,1)).
zoe=1

yes
| ?- display(=(zoe,1)).
=(zoe,1)

yes

You can also use the operator notation as input (as you can see the results are similar to above):

| ?- write(zoe=1).
zoe=1

yes
| ?- display(zoe=1).
=(zoe,1)

You can also define your own operator:

| ?- op(400,xfx,foo).

yes
| ?- write(foo(zoe,1)).
zoe foo 1

yes
| ?- display(foo(zoe,1)).
foo(zoe,1)

yes




This is how arithmetic operations are defined using the 'is' builtin. The 'is' builtin gets a nested function term that uses functors that it interprets as arithmetic operations:
        X is 3 + 4 *  2 * 7.
is the same as
        X is +(3, *(4, *(2, 7))).
The 'is' builtin applies common arithmetic processing to this nested structure to unify a numeric value 59 with X.
Within the context of “is”, does the functor know what it has to do with its arguments or is it the “is” processing code the decides to add, subtract etc. ? I guess that’s an implementation detail and would vary between vendors.
NB: Prolog uses a unified syntax both for the programs (ie. the predicates) and the data (arguments of the predicates). This is nice for meta-programming (Prolog programs handling as data other Prolog programs). In the case of


X is 3 + 4 *  2 * 7.

which is the same as


X is +(3, *(4, *(2, 7))).

It is also the same as:

is(X, +(3, *(4, *(2, 7)))).

| ?- is(X, +(3, *(4, *(2, 7)))).

X = 59

You can now see that the predicate you invoke is called is/2. This is a mathematical predicate which evaluates its second argument (an expression given as a Prolog term) and unifies the result with its first argument.

Daniel

--
Ce message a ete verifie par MailScanner

pour des virus ou des polluriels et rien de
suspect n'a ete trouve.



_______________________________________________
Users-prolog mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/users-prolog