I'd like to call a CLIPS deffunction from C++ and pass it an instance. I am using the standard CLIPS 6.30 distribution (not any C++ bindings). I am currently working with the following definitions:
(defclass CFAM (is-a USER))
(deffunction drop-cfam (?cfam)
(send ?cfam delete))
(definstances KNOWN_THINGS
(cfam-1 of CFAM))
I invoke the function drop-cfam from C++ by passing it the instance address for the instance that I'd like to delete.
void* instancePtr = EnvFindInstance(clipsEnv,NULL,"cfam-1",false);
assert(EnvValidInstanceAddress(clipsEnv,instancePtr));
ostringstream args;
args << instancePtr;
cout << "Calling 'EnvFunctionCall for 'drop-cfam' w/ args: "<< args.str() << endl;
DATA_OBJECT callResult;
const bool callFailed = EnvFunctionCall(clipsEnv,"drop-cfam",args.str().c_str(),&callResult);
assert(!callFailed); // results in abort
const bool droppedCfam = static_cast<bool>(DOToInteger(callResult));
assert(droppedCfam);
An abort occurs on the specified line, while the terminal window displays:
Calling 'EnvFunctionCall for 'drop-cfam' w/ args: 0x274c290
[MSGFUN1] No applicable primary message-handlers found for delete.
[PRCCODE4] Execution halted during the actions of deffunction drop-cfam.
Initially, this suggested that perhaps it is incorrect for me to be passing (what I believe is) an instance address to drop-cfam. However, testing in the terminal suggests that this should not be the problem:
CLIPS> (reset)
CLIPS> (instances)
[initial-object] of INITIAL-OBJECT
[cfam-1] of CFAM
For a total of 2 instances.
CLIPS> (drop-cfam (instance-address [cfam-1]))
TRUE
CLIPS> (instances)
[initial-object] of INITIAL-OBJECT
For a total of 1 instance.
The Advanced Programming Guide (v6.30) states that arguments should be passed to EnvFunctionCall as strings. That section (4.1.10) does not specify any restrictions on data types passed to EnvFunctionCall, and does not reference any other sources that specify lexical forms for data types. I am unsure if I even can pass an instance address via EnvFunctionCall at this time or if my design needs to be modified to avoid it.
EDIT / Workaround
There was an issue in my design where I assumed that my system required an instance address when it did not. The desired behaviour of this question can be achieved by passing the instance name to EnvFunctionCall rather than the address as follows:
EnvFunctionCall(clipsEnv,"drop-cfam","[cfam-1]",&callResult);
Which has the same behaviour as:
CLIPS> (reset)
CLIPS> (drop-cfam [cfam-1])
TRUE
I will still accept any answer that demonstrates how to pass an instance address in a lexical form or describes why the terminal version accepts both instance names and instance addresses.
There is no lexical representation in CLIPS for C pointers (which includes instance, fact and external addresses), so you can't directly specify them. This applies both to the API calls which parse string arguments as well as terminal commands and CLIPS code. During execution addresses can be dynamically bound or returned from function calls and these values can be passed to functions. That's how the instance address is computed from the terminal in your example function call "(drop-cfam (instance-address [cfam-1]))". You can evaluate this same type of expression using EnvEval rather than EnvFunctionCall:
EnvEval(clipsEnv,"(drop-cfam (instance-address [cfam-1]))",&callResult);
Related
We have some async properties (using #property) and some usual ones. We have to use hy to check if one is async or not using asyncio.iscoroutine function. The problem is we have to use getattr and not . operator, since dot will call the property inner function. We want to change our hy code without breaking the DSL used in other projects, that is, we do not want to use string notation (double quotes) for attribute name and therefore we need to write some macro working just like . but internally calls getattr.
=> (defmacro attr [obj attr] `(getattr ~obj '~attr))
=> (attr 5 real)
Traceback (most recent call last):
File "stdin-5bbedde10a6366314d9be4bd343639582b4d0748", line 1, in <module>
(attr 5 real)
AttributeError: 'int' object has no attribute 'real'
=> (. 5 real)
5
It sounds like you're confused about the semantics of Python properties, which is understandable, since they're rather hairy. In Python (and thus also in Hy for the equivalent constructions), foo.x and getattr(foo, "x") are always equivalent, even if x is a property. To get a property method as an object instead of calling it, you need to retrieve the attribute for the class (type(x)) instead of an instance, and getattr with a string literal and . remain interchangeable. In this example, getattr(type(foo), 'bar').fset could also be written as type(foo).bar.fset.
I tried
(defmacro attr [obj attr]
`(getattr ~obj ~(str attr)))
(print (attr 5 real))
in the web interpreter and it prints 5.
I was unable to reproduce your issue in the web interpreter though. It must still be running an older version, because I had to install your exact version to do it. I suspect that the following breaking change announced for 1.0a2 accounts for the difference:
Hy model objects are no longer equal to ordinary Python values. For
example, (!= 1 '1). You can promote values to models with hy.as-model
before making such a check.
My version of attr does work on Hy 1.0a3. I checked. Try it.
Attributes in Python are stored in the object's .__dict__ using string keys. Since Hy's symbols are no longer equal to strings, the lookup of a string key using a symbol will always fail. Converting the symbol to a string first fixes it. My initial comment was correct. (And this step is unnecessary in Hissp because it lacks Hy's separate model types.)
Although the latter answer works, but I found out that the problem is getting the method behind the property and as #kodiologist wrote, getattr and dot are equivalent. SO I used fget and :
(iscoroutinefunction (.fget (. (type obj) ~attr)))
I noticed that there is no
format directive which would
call force-output/finish-output.
Why?
It does seem to be useful in user interaction, cf.
Lisp format and force-output.
E.g., ~= could translate to finish-output, and ~:= to force-output.
I don't think clear-output makes much sense in this context, but we
might map ~#= to it for completeness.
PS. Cf. CLISP RFE.
Summary from comp.lang.lisp:
An explanation from Steven Haflich
The language defines no portable way to extend the set of format
directives (other then ~/.../) but that's not really the issue here.
The real problem is that it is not well defined to call finish-output or similar functions at arbitrary places during printing.
If pretty-printing is in progress, the stream received by a
pprint-dispatch or print-object method may be an encapsulating stream --
one that delays output temporarily until it can make decisions about
white space and line breaks. (There are also potential problems if
finish-output were called inside a ~< justification, but that directive
is a hairball!) What would one expect finish-output to do if called
inside a pretty print operation? I don't think it's well defined.
The problem isn't particular to format, of course, but a directive for
finish-output from format would just add another sharp edge to the
language. finish-output etc. are only safe to call when completely
outside an actual or implied call to cl:write. Call it as a function
at an appropriate point in your code (where you know execution isn't
inside a nested write) so the intention is clear and you don't mess up
printer internals.
A suggestion from Rob Warnock
Actually, no changes to format are needed. Just add this function somewhere in the COMMON-LISP-USER package:
(defun fo (stream arg colon-p atsign-p &rest params)
(declare (ignore arg params))
(cond
(colon-p (force-output stream))
(atsign-p (clear-output stream))
(t (finish-output stream))))
Then:
(progn
(format t "enter var: ~/fo/" nil)
(read))
enter var: 456
456
The problems with this (portable!) approach are
verbosity (~/fo/ instead of ~=)
need to consume a format argument (nil in the example above)
How does one call a method object as a function?
Closer-mop and clos packages both provide method-function for turning a method object into a function. However, is there a way to do it without including another package? And if not, which package? (Using SBCL), but if a package is needed then how does the discrimination function do it?
Here is an example of using find-method to get a method object. The question is then how to call method-to-be-called.
(defclass a () ((x :accessor x :initform 0)))
(defgeneric inc (i))
(defmethod inc ((i a)) (incf (x i)))
(defvar r (make-instance 'a))
;; ... in a land far far away:
(defvar method-to-be-called (find-method #'inc '() '(a)))
(funcall method-to-be-called r);; crashes and burns
As a secondary question, the docs say that the discrimination function first tries to compute-applicable-methods-by-class to find a method object, and if that fails, it uses compute-applicable-methods. Why do this two layer approach? Is it correct to assume the find-method is doing this two layer approach, so it is better to use find-method ?
-- Appendix --
In the comments below Rainer Joswig pointed out that this find-method form is implementation dependent:
(find-method #'inc '() '(a))) ; works on sbcl 1.3.1
He says the specifier list should be classes and suggests instead:
(find-method #'inc '() (list (find-class 'a))))
So I thought to just put my class in there:
(find-method #'inc '() (list a)) ; crashes and burns
Apparently (defclass a ... ) does not set a to a class. In fact it doesn't set it to anything!
* (defclass a () ((x :accessor x :initform 0)))
#<STANDARD-CLASS COMMON-LISP-USER::A>
* a
...
The variable A is unbound.
However, this works:
* (defvar ca (defclass a () ((x :accessor x :initform 0))))
CA
* (defmethod inc ((i a)) (incf (x i)))
WARNING: Implicitly creating new generic function COMMON-LISP-USER::INC.
#<STANDARD-METHOD COMMON-LISP-USER::INC (A) {1005EE8263}>
enter code here
* (find-method #'inc '() (list ca))
#<STANDARD-METHOD COMMON-LISP-USER::INC (A) {1005EE8263}>
*
So a class is the return value from the defclass, not the value of the symbol that is provided to defclass.
(find-method #'inc '() '(a))
Above does not work. We need a list of classes, not a list of symbols.
(funcall (method-function (find-method #'inc
'()
(list (find-class 'a))))
r)
Since the function method-function belongs to the MOP, many implementations provide it and it is in some implementation specific package. CLOSER-MOP makes it available, too.
But usually, if you are already trying extracting method functions, then you are probably using CLOS the wrong way or you are really knowing what you are doing...
How does one call a method object as a function?
Honest question: why do you want to do that? Did you specify how the method's function is built in the first place, or not?
Even with closer-mop, I believe that the function returned by closer-mop:method-function is, at most, consistent with closer-mop:make-method-lambda in terms of its lambda-list, so perhaps you can use a package to know what you can count on portably.
A method's function does not have to be a function with the same lambda-list as the generic function, and usually it isn't due to next-method-p and call-next-method. Some implementations might use dynamic bindings for the next method list, so these might have a method lambda-list congruent with the generic function. Just don't count on it, generically.
I believe SBCL is not one of these implementations, the next method list is passed to the method's function to support next-method-p and call-next-method.
Why do this two layer approach?
Because it allows memoizing (or caching) based on the list of classes, when possible. If the generic function is called again with arguments of the same classes, and the generic function has not been updated (see "Dependent Maintenance Protocol" in the MOP), it can reuse the last result without further processing, for instance, by keeping the results in a hash table which keys are lists of classes.
However, if compute-applicable-methods-using-classes returns a false second value, then compute-applicable-methods is used. The reason is that no method could be found using classes alone, and this means some method has a non-class specializer.
This is different than saying there are no applicable methods, for instance, if all methods are specialized on classes and there are no applicable methods, compute-applicable-methods-using-classes should return an empty list and a true second value. There's no point in calling compute-applicable-methods, it won't (or rather, it shouldn't, if well implemented) find anything further.
It's still possible to perform memoization when compute-applicable-methods is used, but the memoization is no longer as trivial as, for instance, using a list of classes as a key in a hash table. Perhaps you could use a tree structure where you'd try to look up a method for each specializer (instance, then class) sequentially for each argument, until a tree node matched the whole specializable parameter list.
With non-standard specializers, you'd have to change the search order for each node. Unless such specializer's priority is not strictly before, between or after eql and a class, then you're in uncharted areas.
Actually, you'll have to change compute-applicable-methods-using-classes to recognize the non-standard specializers and return false early, and you'll have to change compute-applicable-methods to process these specializers, anyway, so perhaps you'll have a good knowledge on, if possible, how to memoize with the results of compute-applicable-methods anyway.
Is it correct to assume the find-method is doing this two layer approach, so it is better to use find-method ?
No, the purpose of find-method is to find a specific method, not an applicable method. It does not use compute-applicable-methods-using-classes or compute-applicable-methods at all. In fact, it couldn't use the latter ever, as it takes actual arguments instead of specializers.
For the particular case of method-function, closer-mop for SBCL simply reexport the existing symbol from sb-pcl, as seen in closer-mop-packages.lisp. The whole file make use of read-time conditionals (see 1.5.2.1 Use of Implementation-Defined Language Features).
That means that if you are working with SBCL, you might call sb-pcl:method-function (PCL means Portable Common Loops).
The generic function compute-applicable-methods-by-class allows you to know which methods are applicable given classes. This is useful if you don't have actual instances on which you can operate.
It seems also that compute-applicable-methods-using-classes allows the implementation to memoize the applicable methods when the second return value is true. This generic method does not allow you to find applicable methods specialized with eql specializers.
I am speculating here, but it makes sense to fall back on compute-applicable-methods to allow for example eql-specializers or because it is slightly easier to define a method for compute-applicable-methods.
Note the paragraph about consistency:
The following consistency relationship between compute-applicable-methods-using-classes and compute-applicable-methods must be maintained: for any given generic function and set of arguments, if compute-applicable-methods-using-classes returns a second value of true, the first value must be equal to the value that would be returned by a corresponding call to compute-applicable-methods. The results are undefined if a portable method on either of these generic functions causes this consistency to be violated.
I don't think there is a find-method-using-classes generic function specified anywhere.
What is the difference between values and list or cons in Racket or Scheme? When is it better to use one over the other? For example, what would be the disadvantage if quotient/remainder returns (cons _ _) rather than (values _ _)?
Back in 2002 George Caswell asked that question in comp.lang.scheme.
The ensuing thread is long, but has many insights. The discussion
reveals that opinions are divided.
https://groups.google.com/d/msg/comp.lang.scheme/ruhDvI9utVc/786ztruIUNYJ
My answer back then:
> What are the motivations behind Scheme's multiple return values feature?
> Is it meant to reflect the difference in intent, or is there a
> runtime-practical reason?
I imagine the reason being this.
Let's say that need f is called by g. g needs several values from f.
Without multiple value return, f packs the values in a list (or vector),
which is passed to g. g then immediately unpacks the list.
With multple values, the values are just pushed on the stack. Thus no
packing and unpacking is done.
Whether this should be called an optimization hack or not, is up to you.
--
Jens Axel Søgaard
We don't need no side-effecting We don't need no allocation
We don't need no flow control We don't need no special-nodes
No global variables for execution No dark bit-flipping for debugging
Hey! did you leave the args alone? Hey! did you leave those bits alone?
(Chorus) -- "Another Glitch in the Call", a la Pink Floyd
They are semantically the same in Scheme and Racket. In both you need to know how the return looks like to use it.
values is connected to call-with-values and special forms like let-values are just syntax sugar with this procedure call. The user needs to know the form of the result to use call-with-values to make use of the result. A return is often done on a stack and a call is also on a stack. The only reason to favor values in Scheme would be that there are no overhead between the producer return and the consumer call.
With cons (or list) the user needs to know how the data structure of the return looks like. As with values you can use apply instead of call-with-values to do the same thing. As a replacement for let-values (and more) it's easy to make a destructuring-bind macro.
In Common Lisp it's quite different. You can use values always if you have more information to give and the user can still use it as a normal procedure if she only wants to use the first value. Thus for CL you wouldn't need to supply quotient as a variant since quotient/remainder would work just as well. Only when you use special forms or procedures that take multiple values will the fact that the procedure does return more values work the same way as with Scheme. This makes values a better choice in CL than Scheme since you get away with writing one instead of more procedures.
In CL you can access a hash like this:
(gethash 'key *hash* 't)
; ==> T; NIL
If you don't use the second value returned you don't know if T was the default value or the actual value found. Here you see the second value indicating the key was not found in the hash. Often you don't use that value if you know there are only numbers the default value would already be an indication that the key was not found. In Racket:
(hash-ref hash 'key #t)
; ==> #t
In racket failure-result can be a thunk so you get by, but I bet it would return multiple values instead if values did work like in CL. I assume there is more housekeeping with the CL version and Scheme, being a minimalistic language, perhaps didn't want to give the implementors the extra work.
Edit: Missed Alexis' comment on the same topic before posting this
One oft-overlooked practical advantage of using multiple return values over lists is that Racket's compose "just works" with functions that return multiple values:
(define (hello-goodbye name)
(values (format "Hello ~a! " name)
(format "Goodbye ~a." name)))
(define short-conversation (compose string-append hello-goodbye))
> (short-conversation "John")
"Hello John! Goodbye John."
The function produced by compose will pass the two values returned by hello-goodbye as two arguments to string-append. If you're writing code in a functional style with lots of compositions, this is very handy, and it's much more natural than explicitly passing values around yourself with call-with-values and the like.
It's also related to your programming style. If you use values, then it usually means you want to explicitly return n values. Using cons, list or vector usually means you want to return one value which contains something.
There are always pros/cons. For values: It may use less memory on some implemenentations. The caller need to use let-values or other multiple values specific syntax. (I wish I could use just let like CL.)
For cons or other types: You can use let or lambda to receive the returning value. You need to explicitly deconstruct it to get the value you want using car or other procedures.
Which to use and when? Again depending on your programming style and case by case but if the returning value can't be represented in one object (e.g. quotient and remainder), then it might be better to use values to make the procedure's meaning clearer. If the returning value is one object (e.g. name and age for a person), then it might be better to use cons or other constructor (e.g. record).
I am working with CLIPS embedded in a C program, so I have to do everything by C function calls and can't use the CLIPS command line.
Let's say I have asserted a few facts like this:
AssertString("(pizza 1)");
AssertString("(cauliflower 7)");
AssertString("(cheesecake 0)");
Obviously I do not get (let alone retain) any pointers to my facts at this point. When I want to retract a fact later by using Retract(factPtr), I obviously need the pointer to the fact I want to retract. So, after the lines above, how would I find the fact (cauliflower 7) again and get a pointer to it?
Do I have to get the entire fact list by GetFactList([...]), loop through it and compare strings? If so, how would I do that in the multifield DATA_OBJECT this function returns? Or is there a better way?
I would be grateful for any ideas or even code examples.
You can use the fact query functions to query the fact-list and perform actions. You can invoke this through the EvalFunction:
DATA_OBJECT result;
Eval("(do-for-all-facts ((?f pizza)) (eq ?f:implied (create$ 1)) (retract ?f))",&result);
Eval("(do-for-all-facts ((?f cauliflower)) TRUE (retract ?f))",&result);
In the first call, only the pizza fact with the value 1 is retracted. In the second call, all cauliflower facts are retracted.