clipsruby 0.0.5 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +124 -0
- data/ext/clipsruby/clipsruby.c +84 -10
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 75e4ce843f3549eb6b8508d4d97ab8193dc8434acab30659af50871953759991
|
4
|
+
data.tar.gz: 5372088f0743df5a5e3e94833bb7334608bfe85c0ede4879476e3a014eeb034d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e3700fb8eb942640cd698985ecf00190ad447b89dfeed35df3125924e577de0be0f6b56695a1f0e2adfc078b2cdc7655bbdf08c22f40624eb305d4d539da2fd5
|
7
|
+
data.tar.gz: 7626b936453007c332c1cc1f191e449ce3c68f9447281a595fceef524a0cc9bc5a5c603d2afd5553887049d380c6297d0a8e27e9256f9fc54330722cdaaf8ba5
|
data/README.md
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
# clipsruby
|
2
|
+
|
3
|
+
## Description
|
4
|
+
|
5
|
+
Use the CLIPS programming language from within Ruby
|
6
|
+
|
7
|
+
## API
|
8
|
+
|
9
|
+
### `CLIPS.create_environment`
|
10
|
+
### `CLIPS::Environment.new`
|
11
|
+
|
12
|
+
Create a new CLIPS environment in which you may define Rules,
|
13
|
+
assert Facts, and instantiate Objects.
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
env = CLIPS.create_environment
|
17
|
+
env2 = CLIPS::Environment.new
|
18
|
+
```
|
19
|
+
|
20
|
+
### `CLIPS::Environment.assert_string`
|
21
|
+
### `CLIPS::Environment#assert_string`
|
22
|
+
|
23
|
+
Assert a string as a Fact in the CLIPS environment.
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
fact = CLIPS::Environment.assert_string(env, "(foo bar)")
|
27
|
+
fact2 = env.assert_string("(bat baz)")
|
28
|
+
```
|
29
|
+
|
30
|
+
### `CLIPS::Environment.assert_hash`
|
31
|
+
### `CLIPS::Environment#assert_hash`
|
32
|
+
|
33
|
+
Asserts a Deftemplate fact into the CLIPS environment
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
fact = CLIPS::Environment.assert_hash(env, :my_deftemplate, a: 1, b: "asdf", c: :C)
|
37
|
+
fact2 = env.assert_hash(:my_deftemplate, d: 4.5, e: :asdf)
|
38
|
+
```
|
39
|
+
|
40
|
+
### `CLIPS::Environment.find_all_facts`
|
41
|
+
### `CLIPS::Environment#find_all_facts`
|
42
|
+
|
43
|
+
A light wrapper around the CLIPS find-all-facts function. Accepts a fact set template and query,
|
44
|
+
returns Facts in the environment that match as Ruby objects.
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
CLIPS::Environment.find_all_facts(env, "(?f my_deftemplate)")
|
48
|
+
env.find_all_facts("(?f my_deftemplate)")
|
49
|
+
CLIPS::Environment.find_all_facts(env, "(?f my_deftemplate)", "(eq ?f:b \"asdf\")")
|
50
|
+
env.find_all_facts("(?f my_deftemplate)", "(= ?f:a 1)")
|
51
|
+
```
|
52
|
+
|
53
|
+
### `CLIPS::Environment._eval`
|
54
|
+
### `CLIPS::Environment#_eval`
|
55
|
+
|
56
|
+
Evaluates a passed string in the CLIPS environment and returns the results.
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
CLIPS::Environment._eval(env, "(find-all-facts ((?f my_deftemplate)) TRUE)")
|
60
|
+
env._eval("(find-all-facts ((?f my_deftemplate)) TRUE)")
|
61
|
+
```
|
62
|
+
|
63
|
+
### `CLIPS::Environment.build`
|
64
|
+
### `CLIPS::Environment#build`
|
65
|
+
|
66
|
+
Build the constructs in the env as defined in a string
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
CLIPS::Environment.build(env, "(deftemplate my_template (slot a) (slot b) (slot c))")
|
70
|
+
env.build("(defrule do-a-thing (my_template (a ?a)) => (println \"a: \" ?a))")
|
71
|
+
```
|
72
|
+
|
73
|
+
### `CLIPS::Environment.add_udf`
|
74
|
+
### `CLIPS::Environment#add_udf`
|
75
|
+
|
76
|
+
Adds a ruby method as a User Defined Function (udf) to the CLIPS environment
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
class CLIPS::Environment
|
80
|
+
def foo(a, b=2)
|
81
|
+
a + b
|
82
|
+
end
|
83
|
+
|
84
|
+
def bar(word)
|
85
|
+
"You said #{word}!"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
env.add_udf(:foo)
|
90
|
+
CLIPS::Environment.add_udf(env, :bar)
|
91
|
+
```
|
92
|
+
|
93
|
+
### `CLIPS::Environment.run`
|
94
|
+
### `CLIPS::Environment#run`
|
95
|
+
|
96
|
+
Runs the rules engine, executing items on the agenda.
|
97
|
+
Optionally may take the number of items to run from the agenda as an argument.
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
CLIPS::Environment.run(env, 1)
|
101
|
+
CLIPS::Environment.run(env)
|
102
|
+
env.run(1)
|
103
|
+
env.run
|
104
|
+
```
|
105
|
+
|
106
|
+
### `CLIPS::Environment.facts`
|
107
|
+
### `CLIPS::Environment#facts`
|
108
|
+
|
109
|
+
Print all Facts defined in the CLIPS environment
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
CLIPS::Environment.facts(env)
|
113
|
+
env.facts
|
114
|
+
```
|
115
|
+
|
116
|
+
### `CLIPS::Environment::Fact.deftemplate_name`
|
117
|
+
### `CLIPS::Environment::Fact#deftemplate_name`
|
118
|
+
|
119
|
+
Returns the name of the Deftemplate for a fact as a symbol
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
CLIPS::Environment::Fact.deftemplate_name(fact)
|
123
|
+
fact.deftemplate_name
|
124
|
+
```
|
data/ext/clipsruby/clipsruby.c
CHANGED
@@ -323,8 +323,10 @@ static VALUE clips_environment_static_assert_hash(VALUE self, VALUE environment,
|
|
323
323
|
return clips_environment_assert_hash(environment, deftemplate_name, hash);
|
324
324
|
}
|
325
325
|
|
326
|
-
static void CLIPSValue_to_VALUE(CLIPSValue *from, VALUE *value,
|
326
|
+
static void CLIPSValue_to_VALUE(CLIPSValue *from, VALUE *value, VALUE *rbEnvironment)
|
327
327
|
{
|
328
|
+
Environment *env;
|
329
|
+
TypedData_Get_Struct(*rbEnvironment, Environment, &Environment_type, env);
|
328
330
|
switch (from->header->type)
|
329
331
|
{
|
330
332
|
case VOID_TYPE:
|
@@ -338,7 +340,7 @@ static void CLIPSValue_to_VALUE(CLIPSValue *from, VALUE *value, Environment *env
|
|
338
340
|
for (size_t i = 0; i < from->multifieldValue->length; i++)
|
339
341
|
{
|
340
342
|
VALUE innerValue;
|
341
|
-
CLIPSValue_to_VALUE(&from->multifieldValue->contents[i], &innerValue,
|
343
|
+
CLIPSValue_to_VALUE(&from->multifieldValue->contents[i], &innerValue, rbEnvironment);
|
342
344
|
rb_ary_push(*value, innerValue);
|
343
345
|
}
|
344
346
|
break;
|
@@ -358,8 +360,13 @@ static void CLIPSValue_to_VALUE(CLIPSValue *from, VALUE *value, Environment *env
|
|
358
360
|
case INSTANCE_NAME_TYPE:
|
359
361
|
*value = rb_str_new2(from->lexemeValue->contents);
|
360
362
|
break;
|
361
|
-
case EXTERNAL_ADDRESS_TYPE:
|
362
363
|
case FACT_ADDRESS_TYPE:
|
364
|
+
*value =
|
365
|
+
TypedData_Wrap_Struct(rb_const_get(CLASS_OF(*rbEnvironment), rb_intern("Fact")), &Fact_type, from->factValue);
|
366
|
+
|
367
|
+
rb_iv_set(*value, "@environment", *rbEnvironment);
|
368
|
+
break;
|
369
|
+
case EXTERNAL_ADDRESS_TYPE:
|
363
370
|
case INSTANCE_ADDRESS_TYPE:
|
364
371
|
default:
|
365
372
|
WriteString(env,STDERR,"Unsupported data type returned from function\n");
|
@@ -368,8 +375,10 @@ static void CLIPSValue_to_VALUE(CLIPSValue *from, VALUE *value, Environment *env
|
|
368
375
|
}
|
369
376
|
}
|
370
377
|
|
371
|
-
static void UDFValue_to_VALUE(UDFValue *from, VALUE *value,
|
378
|
+
static void UDFValue_to_VALUE(UDFValue *from, VALUE *value, VALUE *rbEnvironment)
|
372
379
|
{
|
380
|
+
Environment *env;
|
381
|
+
TypedData_Get_Struct(*rbEnvironment, Environment, &Environment_type, env);
|
373
382
|
switch (from->header->type)
|
374
383
|
{
|
375
384
|
case VOID_TYPE:
|
@@ -383,7 +392,7 @@ static void UDFValue_to_VALUE(UDFValue *from, VALUE *value, Environment *env)
|
|
383
392
|
VALUE innerValue;
|
384
393
|
for (size_t i = 0; i < from->multifieldValue->length; i++)
|
385
394
|
{
|
386
|
-
CLIPSValue_to_VALUE(&from->multifieldValue->contents[i], &innerValue,
|
395
|
+
CLIPSValue_to_VALUE(&from->multifieldValue->contents[i], &innerValue, rbEnvironment);
|
387
396
|
rb_ary_push(*value, innerValue);
|
388
397
|
}
|
389
398
|
break;
|
@@ -403,8 +412,13 @@ static void UDFValue_to_VALUE(UDFValue *from, VALUE *value, Environment *env)
|
|
403
412
|
case INSTANCE_NAME_TYPE:
|
404
413
|
*value = rb_str_new2(from->lexemeValue->contents);
|
405
414
|
break;
|
406
|
-
case EXTERNAL_ADDRESS_TYPE:
|
407
415
|
case FACT_ADDRESS_TYPE:
|
416
|
+
*value =
|
417
|
+
TypedData_Wrap_Struct(rb_const_get(CLASS_OF(*rbEnvironment), rb_intern("Fact")), &Fact_type, from->factValue);
|
418
|
+
|
419
|
+
rb_iv_set(*value, "@environment", *rbEnvironment);
|
420
|
+
break;
|
421
|
+
case EXTERNAL_ADDRESS_TYPE:
|
408
422
|
case INSTANCE_ADDRESS_TYPE:
|
409
423
|
default:
|
410
424
|
WriteString(env,STDERR,"Unsupported data type returned from function\n");
|
@@ -423,11 +437,11 @@ void UDFGenericFunction(
|
|
423
437
|
VALUE *current_argv = argv;
|
424
438
|
UDFValue theArg;
|
425
439
|
VALUE method = (VALUE)(context->context);
|
426
|
-
VALUE
|
440
|
+
VALUE rbEnvironment = rb_funcall(method, rb_intern("receiver"), 0);
|
427
441
|
while (UDFHasNextArgument(context))
|
428
442
|
{
|
429
443
|
UDFNextArgument(context, ANY_TYPE_BITS, &theArg);
|
430
|
-
UDFValue_to_VALUE(&theArg, current_argv,
|
444
|
+
UDFValue_to_VALUE(&theArg, current_argv, &rbEnvironment);
|
431
445
|
current_argv++;
|
432
446
|
}
|
433
447
|
// Call the method on the object with the provided arguments
|
@@ -570,7 +584,7 @@ static VALUE clips_environment_run(int argc, VALUE *argv, VALUE environment) {
|
|
570
584
|
|
571
585
|
TypedData_Get_Struct(environment, Environment, &Environment_type, env);
|
572
586
|
|
573
|
-
return
|
587
|
+
return INT2NUM(Run(env, NUM2INT(integer)));
|
574
588
|
}
|
575
589
|
|
576
590
|
static VALUE clips_environment_static_run(int argc, VALUE *argv, VALUE klass) {
|
@@ -584,7 +598,63 @@ static VALUE clips_environment_static_run(int argc, VALUE *argv, VALUE klass) {
|
|
584
598
|
|
585
599
|
TypedData_Get_Struct(environment, Environment, &Environment_type, env);
|
586
600
|
|
587
|
-
return
|
601
|
+
return INT2NUM(Run(env, NUM2INT(integer)));
|
602
|
+
}
|
603
|
+
|
604
|
+
static VALUE clips_environment_eval(VALUE self, VALUE string)
|
605
|
+
{
|
606
|
+
Environment *env;
|
607
|
+
CLIPSValue output;
|
608
|
+
VALUE toReturn;
|
609
|
+
|
610
|
+
TypedData_Get_Struct(self, Environment, &Environment_type, env);
|
611
|
+
|
612
|
+
switch(Eval(env, StringValueCStr(string), &output))
|
613
|
+
{
|
614
|
+
case EE_NO_ERROR:
|
615
|
+
break;
|
616
|
+
case EE_PROCESSING_ERROR:
|
617
|
+
rb_warn("`eval` failed!");
|
618
|
+
break;
|
619
|
+
case EE_PARSING_ERROR:
|
620
|
+
rb_warn("`eval` failed! Could not parse string correctly.");
|
621
|
+
break;
|
622
|
+
}
|
623
|
+
|
624
|
+
CLIPSValue_to_VALUE(&output, &toReturn, &self);
|
625
|
+
|
626
|
+
return toReturn;
|
627
|
+
}
|
628
|
+
|
629
|
+
static VALUE clips_environment_static_eval(VALUE self, VALUE rbEnvironment, VALUE string)
|
630
|
+
{
|
631
|
+
return clips_environment_eval(rbEnvironment, string);
|
632
|
+
}
|
633
|
+
|
634
|
+
static VALUE clips_environment_find_all_facts(int argc, VALUE *argv, VALUE environment) {
|
635
|
+
VALUE fact_set_template, query;
|
636
|
+
|
637
|
+
rb_scan_args(argc, argv, "11", &fact_set_template, &query);
|
638
|
+
if (NIL_P(query)) {
|
639
|
+
query = rb_str_new_cstr("TRUE");
|
640
|
+
}
|
641
|
+
|
642
|
+
return clips_environment_eval(
|
643
|
+
environment,
|
644
|
+
rb_sprintf("(find-all-facts (%s) %s)", StringValueCStr(fact_set_template), StringValueCStr(query)));
|
645
|
+
}
|
646
|
+
|
647
|
+
static VALUE clips_environment_static_find_all_facts(int argc, VALUE *argv, VALUE klass) {
|
648
|
+
VALUE rbEnvironment, fact_set_template, query;
|
649
|
+
|
650
|
+
rb_scan_args(argc, argv, "21", &rbEnvironment, &fact_set_template, &query);
|
651
|
+
if (NIL_P(query)) {
|
652
|
+
query = rb_str_new_cstr("TRUE");
|
653
|
+
}
|
654
|
+
|
655
|
+
return clips_environment_eval(
|
656
|
+
rbEnvironment,
|
657
|
+
rb_sprintf("(find-all-facts (%s) %s)", StringValueCStr(fact_set_template), StringValueCStr(query)));
|
588
658
|
}
|
589
659
|
|
590
660
|
void Init_clipsruby(void)
|
@@ -606,6 +676,10 @@ void Init_clipsruby(void)
|
|
606
676
|
rb_define_method(rbEnvironment, "add_udf", clips_environment_add_udf, -1);
|
607
677
|
rb_define_singleton_method(rbEnvironment, "run", clips_environment_static_run, -1);
|
608
678
|
rb_define_method(rbEnvironment, "run", clips_environment_run, -1);
|
679
|
+
rb_define_singleton_method(rbEnvironment, "_eval", clips_environment_static_eval, 2);
|
680
|
+
rb_define_method(rbEnvironment, "_eval", clips_environment_eval, 1);
|
681
|
+
rb_define_singleton_method(rbEnvironment, "find_all_facts", clips_environment_static_find_all_facts, -1);
|
682
|
+
rb_define_method(rbEnvironment, "find_all_facts", clips_environment_find_all_facts, -1);
|
609
683
|
|
610
684
|
VALUE rbFact = rb_define_class_under(rbEnvironment, "Fact", rb_cObject);
|
611
685
|
rb_define_singleton_method(rbFact, "deftemplate_name", clips_environment_fact_static_deftemplate_name, 1);
|
metadata
CHANGED
@@ -1,22 +1,24 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: clipsruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Johnston
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-09-
|
11
|
+
date: 2024-09-05 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Calling the CLIPS programming language from within Ruby
|
14
14
|
email: mrryanjohnston@gmail.com
|
15
15
|
executables: []
|
16
16
|
extensions:
|
17
17
|
- ext/clipsruby/extconf.rb
|
18
|
-
extra_rdoc_files:
|
18
|
+
extra_rdoc_files:
|
19
|
+
- README.md
|
19
20
|
files:
|
21
|
+
- README.md
|
20
22
|
- ext/clipsruby/agenda.c
|
21
23
|
- ext/clipsruby/agenda.h
|
22
24
|
- ext/clipsruby/analysis.c
|