When passing an instance name to a UDF directly via a make-instance, FindInstance is not able to find the instance with the given instance name returned from make-instance. However, if you first save the result of running make-instance in a defglobal and then pass the defglobal to the UDF, it is able to find it.
I tested this with latest from 64x svn branch. Here is my main.c:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.40 08/06/16 */
/* */
/* MAIN MODULE */
/*******************************************************/
/*************************************************************/
/* Purpose: */
/* */
/* Principal Programmer(s): */
/* Gary D. Riley */
/* */
/* Contributing Programmer(s): */
/* */
/* Revision History: */
/* */
/* 6.24: Moved UserFunctions and EnvUserFunctions to */
/* the new userfunctions.c file. */
/* */
/* 6.40: Removed use of void pointers for specific */
/* data structures. */
/* */
/* Moved CatchCtrlC to main.c. */
/* */
/*************************************************************/
/***************************************************************************/
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, and/or sell copies of the Software, and to permit persons */
/* to whom the Software is furnished to do so. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS */
/* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT */
/* OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY */
/* CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES */
/* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN */
/* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF */
/* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
/* */
/***************************************************************************/
#include "clips.h"
#if UNIX_V || LINUX || DARWIN || UNIX_7 || WIN_GCC || WIN_MVC
#include <signal.h>
#endif
/***************************************/
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
/***************************************/
#if UNIX_V || LINUX || DARWIN || UNIX_7 || WIN_GCC || WIN_MVC
static void CatchCtrlC(int);
#endif
/***************************************/
/* LOCAL INTERNAL VARIABLE DEFINITIONS */
/***************************************/
static Environment *mainEnv;
/****************************************/
/* main: Starts execution of the expert */
/* system development environment. */
/****************************************/
int main(
int argc,
char *argv[])
{
mainEnv = CreateEnvironment();
#if UNIX_V || LINUX || DARWIN || UNIX_7 || WIN_GCC || WIN_MVC
signal(SIGINT,CatchCtrlC);
#endif
Build(mainEnv, "(defclass A (is-a USER))");
Eval(mainEnv, "(println \"First: \" (do (make-instance of A)))", NULL);
Build(mainEnv, "(defglobal ?*a* = (make-instance of A))");
Eval(mainEnv, "(println \"Second: \" (do ?*a*))", NULL);
RerouteStdin(mainEnv,argc,argv);
CommandLoop(mainEnv);
/*==================================================================*/
/* Control does not normally return from the CommandLoop function. */
/* However if you are embedding CLIPS, have replaced CommandLoop */
/* with your own embedded calls that will return to this point, and */
/* are running software that helps detect memory leaks, you need to */
/* add function calls here to deallocate memory still being used by */
/* CLIPS. If you have a multi-threaded application, no environments */
/* can be currently executing. */
/*==================================================================*/
DestroyEnvironment(mainEnv);
return -1;
}
#if UNIX_V || LINUX || DARWIN || UNIX_7 || WIN_GCC || WIN_MVC || DARWIN
/***************/
/* CatchCtrlC: */
/***************/
static void CatchCtrlC(
int sgnl)
{
SetHaltExecution(mainEnv,true);
CloseAllBatchSources(mainEnv);
signal(SIGINT,CatchCtrlC);
}
#endif
Here is my userfunctions.c:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.40 07/30/16 */
/* */
/* USER FUNCTIONS MODULE */
/*******************************************************/
/*************************************************************/
/* Purpose: */
/* */
/* Principal Programmer(s): */
/* Gary D. Riley */
/* */
/* Contributing Programmer(s): */
/* */
/* Revision History: */
/* */
/* 6.24: Created file to seperate UserFunctions and */
/* EnvUserFunctions from main.c. */
/* */
/* 6.30: Removed conditional code for unsupported */
/* compilers/operating systems (IBM_MCW, */
/* MAC_MCW, and IBM_TBC). */
/* */
/* Removed use of void pointers for specific */
/* data structures. */
/* */
/*************************************************************/
/***************************************************************************/
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, and/or sell copies of the Software, and to permit persons */
/* to whom the Software is furnished to do so. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS */
/* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT */
/* OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY */
/* CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES */
/* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN */
/* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF */
/* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
/* */
/***************************************************************************/
#include "clips.h"
void UserFunctions(Environment *);
void DoFunction(Environment *theEnv, UDFContext *context, UDFValue *returnValue)
{
UDFValue theArg;
UDFNextArgument(context,INSTANCE_NAME_BIT,&theArg);
if (theArg.header->type != INSTANCE_NAME_TYPE)
{
WriteString(theEnv, STDERR, "do: first arg must be an instance name\n");
returnValue->lexemeValue = FalseSymbol(theEnv);
return;
}
if (NULL == FindInstance(theEnv, NULL, theArg.lexemeValue->contents, true))
{
WriteString(theEnv, STDERR, "do: could not find instance of name ");
WriteString(theEnv, STDERR, theArg.lexemeValue->contents);
WriteString(theEnv, STDERR, "\n");
returnValue->lexemeValue = FalseSymbol(theEnv);
return;
}
returnValue->lexemeValue = TrueSymbol(theEnv);
}
/*********************************************************/
/* UserFunctions: Informs the expert system environment */
/* of any user defined functions. In the default case, */
/* there are no user defined functions. To define */
/* functions, either this function must be replaced by */
/* a function with the same name within this file, or */
/* this function can be deleted from this file and */
/* included in another file. */
/*********************************************************/
void UserFunctions(
Environment *env)
{
#if MAC_XCD
#pragma unused(env)
#endif
AddUDF(env,"do","b",1,1,";n",DoFunction,"DoFunction",NULL);
}
Here is the output from running ./clips after compiling with the above changes:
$ ./clips
do: could not find instance of name gen1
First: FALSE
Second: TRUE
CLIPS (6.4.3 5/26/25)
CLIPS>
Anonymous
Fixed check into SVN repository.