Skip to content

Instantly share code, notes, and snippets.

@mrryanjohnston
Created March 19, 2021 14:59
Show Gist options
  • Save mrryanjohnston/4c0bd8e06efc1abd26c9cb9b62795610 to your computer and use it in GitHub Desktop.
Save mrryanjohnston/4c0bd8e06efc1abd26c9cb9b62795610 to your computer and use it in GitHub Desktop.
clips-redis
#include "clips.h"
#include <hiredis.h>
#include <signal.h>
#include <stdbool.h>
#include <stdlib.h>
void INThandler(int sig);
/****************************************/
/* main: Starts execution of the expert */
/* system development environment. */
/****************************************/
int main(
int argc,
char *argv[])
{
void *theEnv;
theEnv = CreateEnvironment();
RerouteStdin(theEnv,argc,argv);
redisContext *c = redisConnect("127.0.0.1", 6379);
if (c == NULL || c->err) {
if (c) {
printf("Error: %s\n", c->errstr);
return(-1);
} else {
printf("Can't allocate redis context\n");
return(-1);
}
}
redisReply *reply = redisCommand(c,"SUBSCRIBE foo");
freeReplyObject(reply);
signal(SIGINT, INThandler);
bool keepRunning = true;
EnvLoad(theEnv, "rules.clp");
EnvLoadFacts(theEnv, "facts.clp");
EnvRun(theEnv, -1);
EnvAssertString(theEnv, "(next-state)");
EnvRun(theEnv, -1);
EnvAssertString(theEnv, "(next-state)");
EnvRun(theEnv, -1);
while(keepRunning && redisGetReply(c,(void *)&reply) == REDIS_OK) {
printf("Got array with %d elements!\n", reply->elements);
if (reply->type == REDIS_REPLY_STRING) {
printf("Got string from redis: %s\n", reply->str);
} else if (reply->type == REDIS_REPLY_ARRAY) {
printf("Got array from redis: %s\n", reply->element[0]->str);
printf("Got array from redis: %s\n", reply->element[1]->str);
printf("Got array from redis: %s\n", reply->element[2]->str);
} else {
printf("Got something other than string: %s\n", reply->str);
//printf("Bye!");
//keepRunning = false;
}
freeReplyObject(reply);
}
redisFree(c);
DeallocateEnvironmentData();
DestroyEnvironment(theEnv);
return(0);
}
void INThandler(int sig)
{
char c;
signal(sig, SIG_IGN);
printf("OUCH, did you hit Ctrl-C?\n"
"Do you really want to quit? [y/n] ");
c = getchar();
if (c == 'y' || c == 'Y')
exit(0);
else
signal(SIGINT, INThandler);
getchar(); // Get new line character
}
#include "clips.h"
#include <hiredis.h>
void UserFunctions(void);
void EnvUserFunctions(void *);
void UserFunctions()
{
}
double clipsRedisPublish(void *environment)
{
printf("HELLO?\n");
if (EnvArgCountCheck(environment, "clipsRedisPublish", EXACTLY, 4) == -1) {
return(-1);
}
const char *ip = EnvRtnLexeme(environment, 1);
double port = EnvRtnDouble(environment, 2);
const char *topic = EnvRtnLexeme(environment, 3);
const char *message = EnvRtnLexeme(environment, 4);
redisContext *c = redisConnect(ip, port);
if (c == NULL || c->err) {
if (c) {
printf("Error: %s\n", c->errstr);
return(-1);
} else {
printf("Can't allocate redis context\n");
return(-1);
}
}
redisReply *reply = redisCommand(c,"PUBLISH %s %s", topic, message);
freeReplyObject(reply);
printf("HELLO!\n");
return;
}
double clipsRedisSetValue(void *environment)
{
printf("HELLO?\n");
if (EnvArgCountCheck(environment, "clipsRedisSetValue", EXACTLY, 4) == -1) {
return(-1);
}
const char *ip = EnvRtnLexeme(environment, 1);
double port = EnvRtnDouble(environment, 2);
const char *key = EnvRtnLexeme(environment, 3);
const char *value = EnvRtnLexeme(environment, 4);
redisContext *c = redisConnect(ip, port);
if (c == NULL || c->err) {
if (c) {
printf("Error: %s\n", c->errstr);
return(-1);
} else {
printf("Can't allocate redis context\n");
return(-1);
}
}
redisReply *reply = redisCommand(c,"SET %s %s", key, value);
freeReplyObject(reply);
printf("HELLO!\n");
return;
}
void EnvUserFunctions(
void *environment)
{
#if MAC_XCD
#pragma unused(environment)
#endif
/*
extern double clipsRedisPublish(void *foo);
extern double clipsRedisSetValue(void *foo);
*/
printf("HI");
EnvDefineFunction(environment,"clipsRedisPublish",'v',PTIEF clipsRedisPublish,"clipsRedisPublish");
EnvDefineFunction(environment,"clipsRedisSetValue",'v',PTIEF clipsRedisSetValue,"clipsRedisSetValue");
}
@mrryanjohnston
Copy link
Author

mrryanjohnston commented Mar 19, 2021

Could be used in a rule like:

(defrule MAIN::change-state-init-inactive-neighbors
   ?next <- (next-state)
   ?state <- (state init-inactive-neighbors)
   =>
   (retract ?next)
   (retract ?state)
(clipsRedisPublish "127.0.0.1" "6379" foo bar)
(clipsRedisSetValue "127.0.0.1" "6379" foo bar)
   (assert (state init-neighbors)))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment