Finding object type

1 view
Skip to first unread message

Rangarajan Krishnamoorthy

unread,
Nov 17, 2018, 11:57:05 PM11/17/18
to ErgoAI-Flor...@coherentknowledge.com
Hi,
If a variable is bound to a value of some type T at runtime, is there a way to get that type? Is there an equivalent of “typeid()” in C++ or “getClass()” in Java?

For example, if I have a UDF:

\udf fooBar(?arg1, ?arg2) := <Body>

I want to get the type of ?arg1 and ?arg2 in the <Body>.

Is this possible?

Regards,
Rangarajan

Paul Fodor

unread,
Nov 18, 2018, 9:45:03 AM11/18/18
to ErgoAI-Flor...@coherentknowledge.com
You can check what is the type of variables as described in Chapter 14:  Testing Meta-properties of Symbols and Variables in  http://coherentknowledge.com/coherent-links/ergo-manual.pdf
isnumber{Arg} — tests whether the argument is (or is bound to) a number. 
isinteger{Arg} — tests whether the argument is (or is bound to) an integer number. 
isfloat{Arg} — tests whether the argument is (or is bound to) a floating point number. 
isdecimal{Arg} — tests if the argument is (or is bound to) a decimal number. At present, this is the same as isnumber{Arg}  
...

and then define your function to return different expressions depending on the type
\udf f(?X) := =?X+5 \if isnumber{?X}.
\udf f(?X) := ?X \if islist{?X}. 


 


--
You received this message because you are subscribed to the Google Groups "ErgoAI, Flora-2, and XSB Users Forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ErgoAI-Flora2-XSB...@coherentknowledge.com.
To post to this group, send email to ErgoAI-Flor...@coherentknowledge.com.
Visit this group at https://groups.google.com/a/coherentknowledge.com/group/ErgoAI-Flora2-XSB-forum/.
To view this discussion on the web visit https://groups.google.com/a/coherentknowledge.com/d/msgid/ErgoAI-Flora2-XSB-forum/D659F25B-D8EE-4599-ACCB-659732BF1027%40gmail.com.


--
-------------------------------
Paul Fodor, PhD
E-mail: paul....@coherentknowledge.com
http://www.coherentknowledge.com
-------------------------------

Michael Kifer

unread,
Nov 18, 2018, 2:52:25 PM11/18/18
to ErgoAI, Flora-2, and XSB Users Forum
By type do you mean primitive types or class membership?  In any case, as Paul suggested, you need a separate case for each type/class and then (maybe) the default or error case. You might need to use the cut(!) because not all types are disjoint. You can also use the ?X^^type idiom instead of the explicit type checks.

Rangarajan Krishnamoorthy

unread,
Nov 18, 2018, 6:30:51 PM11/18/18
to Michael Kifer, ErgoAI, Flora-2, and XSB Users Forum
Both primitives and class memberships. The “is…” family of functions returns boolean. This forces me to enumerate many cases. But if I have access to the class description of a variable ?x, then I can (if needed), compare that with the description of another variable ?y and see if they are same.

getClass(?x) == getClass(?y)

- Rangarajan
--
You received this message because you are subscribed to the Google Groups "ErgoAI, Flora-2, and XSB Users Forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ErgoAI-Flora2-XSB...@coherentknowledge.com.
To post to this group, send email to ErgoAI-Flor...@coherentknowledge.com.
Visit this group at https://groups.google.com/a/coherentknowledge.com/group/ErgoAI-Flora2-XSB-forum/.

Michael Kifer

unread,
Nov 18, 2018, 7:25:57 PM11/18/18
to Rangarajan Krishnamoorthy, ErgoAI, Flora-2, and XSB Users Forum

On 11/18/18 6:30 PM, Rangarajan Krishnamoorthy wrote:
Both primitives and class memberships. The “is…” family of functions returns boolean. This forces me to enumerate many cases. But if I have access to the class description of a variable ?x, then I can (if needed), compare that with the description of another variable ?y and see if they are same.

getClass(?x) == getClass(?y)


But the class hierarchy can be complex with multiple inheritance. The above test gives you absolutely nothing and is procedural, not declarative, thinking.

Note:


ergo> ?X^^foo = ?Y^^bar, writeln(?X)@\plg.
_h12171 { \$typed variable : type = (bar,foo) }


After unification, this becomes one variable that can still be bound to something that belongs both to the classes bar and  foo.


In sum, for variables, getClass(...) is useless. For objects, one can define  getClass(?inobj,?outclass)  to yield the most immediate class(es) of an object, but the result (?outclass) may not be unique and may not even exist for some hierarchies.

--

       --- michael


Rangarajan Krishnamoorthy

unread,
Nov 18, 2018, 8:42:47 PM11/18/18
to Michael Kifer, ErgoAI, Flora-2, and XSB Users Forum
You are right. I completely forgot for a moment that we can do this in Flora-2:
anObj : {Class1, Class2}.

In languages such as C++ we usually do something that is the equivalent of:
Derived :: {Class1, Class2}.
anObj : Derived.

In this case, for every object, there is just one class it is an instance of, so getClass() makes sense.

As to your other observation that this is procedural thinking, you may be right, but Flora-2 has constructs that are used in procedural languages, and thus allows the programmer to choose the appropriate construct for a specific problem.

- Rangarajan

Rangarajan Krishnamoorthy

unread,
Nov 18, 2018, 9:19:14 PM11/18/18
to Michael Kifer, Paul Fodor, ErgoAI, Flora-2, and XSB Users Forum
Let us say that I want to implement my own function despatcher:
despatch(foo, ?arg)
What this UDF does is to determine the most specific ‘foo' that matches the type of ?arg and then apply that UDF on ?arg. So, in our example,
despatch(foo, bObj) will invoke the ‘foo’ that corresponds to B type object (the first foo) and return 1
despatch(foo, aObj) will invoke the ‘foo’ that corresponds to A type object (the second foo) and return 2

Note that if the first ‘foo’ is not defined in the system, then ‘despatch’ will only invoke the same ‘foo’ on both A and B objects. So, the discrimination cannot be done at the level of the ‘foo' (I think) but at the level of the despatcher.

Does this make sense?

- Rangarajan

On 19-Nov-2018, at 6:02 AM, Michael Kifer <michae...@coherentknowledge.com> wrote:

good. It can be further simplified to

\udf foo(?arg) := 1 \if ?arg:B, !.
\udf foo(?arg) := 2 \if ?arg:A. 

--

       --- michael



On 11/18/18 3:02 PM, Paul Fodor wrote:
I sent Rangarajan some examples earlier today.
Paul.

On Sun, Nov 18, 2018 at 1:06 PM Paul Fodor <paul....@coherentknowledge.com> wrote:
Yes.

B::A.

\udf foo(?arg) := 1 \if ?arg:B.

\udf foo(?arg) := 2 \if ?arg:A, \naf ?arg:B.

bob:B.
anne:A.

%test1 :-
writeln( foo(bob) )@\plg.

%test2 :-
writeln( foo(anne) )@\plg.

?- %test1.

?- %test2.



On Sun, Nov 18, 2018 at 10:21 AM Rangarajan Krishnamoorthy <rang...@gmail.com> wrote:
OK, got it. Here is what I would like to do. Given two UDFs,
foo(?arg^^A) and foo(?arg^^B) (with respective bodies), 
and two classes A, B such that B::A
I want to be able to introspect using “clause{}” and determine that foo(?arg^^B) is more “specific” than foo(?arg^^A) with respect to that hierarchy.

Is this possible?

- Rangarajan

On 18-Nov-2018, at 8:33 PM, Paul Fodor <paul....@coherentknowledge.com> wrote:

That you can do with 
?X:name.

On Sun, Nov 18, 2018 at 9:51 AM Rangarajan Krishnamoorthy <rang...@gmail.com> wrote:
Yes, I saw this section. These are boolean queries. What about classes? What I am looking for is some representation of the type itself, for example, name, etc. Something equivalent to the C++/Java feature.

- Rangarajan



-- 
-------------------------------
Paul Fodor, PhD
E-mail: paul....@coherentknowledge.com
http://www.coherentknowledge.com
-------------------------------


-- 
-------------------------------
Paul Fodor, PhD
E-mail: paul....@coherentknowledge.com
http://www.coherentknowledge.com
-------------------------------

Rangarajan Krishnamoorthy

unread,
Nov 18, 2018, 9:40:24 PM11/18/18
to Michael Kifer, Paul Fodor, ErgoAI, Flora-2, and XSB Users Forum
By the way, is it not better to define the functions this way (in your example)?

foo(?arg^^B) := 1 \if ?arg:B, !.
foo(?arg^^A) := 2 

I thought giving the type spec was more efficient (the RHS might do additional checks).

- Rangarajan

Michael Kifer

unread,
Nov 18, 2018, 9:41:51 PM11/18/18
to Rangarajan Krishnamoorthy, Paul Fodor, ErgoAI, Flora-2, and XSB Users Forum

I am lost in your description below, but to find the most specific class one would do something like this:


msc(?obj,?cl) :- ?obj:?cl, \naf (?subcl::?cl, ?obj:?subcl).


Note that the MSC is often not unique and may not exist.

The latter is because one can define an infinite sequence of classes such that  foo : cl_i,  for all  i=0,1,2,3,...

and  ... :: cl_4 :: cl_3 :: cl_2 :: cl_1 :: cl_0.


In this case, msc(foo,?cl) won't terminate, but, of course, one must work hard to create such a situation.

If you have a hairy class hierarchy then the above will also be inefficient.

But if your hierarchy is finite, well-designed, and is similar to what people do in procedural OO languages then it'll be ok.


Anyway, with this msc you can dispatch whatever possibly makes sense to dispatch.

--

       --- michael


Rangarajan Krishnamoorthy

unread,
Nov 18, 2018, 9:44:33 PM11/18/18
to Michael Kifer, Paul Fodor, ErgoAI, Flora-2, and XSB Users Forum
Thanks Michael. Let me do my homework!

- Rangarajan

Michael Kifer

unread,
Nov 18, 2018, 9:52:04 PM11/18/18
to Rangarajan Krishnamoorthy, Paul Fodor, ErgoAI, Flora-2, and XSB Users Forum

Did you mean this?

\udf foo(?_arg^^B) := 1 \if !.
\udf foo(?_arg^^A) := 2.


Yes, it is better.

--

       --- michael


Reply all
Reply to author
Forward
0 new messages