Added -pedantic and -ansi to CFLAGS and cleaned warnings
[rice.git] / src / infer.c
blob742906dfb959cfdfecf11d380fd4f019c3062073
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * RICE 4.0x Copyright (C) 1993 Rene' Jager *
3 * *
4 * *
5 * This toolbox is free software; you can redistribute it and/or *
6 * modify it under the terms of the GNU General Public License as *
7 * published by the Free Software Foundation; either version 2 of *
8 * the License, or (at your option) any later version. *
9 * *
10 * This toolbox is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this toolbox; if not, write to the: *
17 * *
18 * Free Software Foundation, Inc. *
19 * 675 Mass Ave, Cambridge *
20 * MA 02139, USA. *
21 * *
22 * See the RICE documentation for more information on the toolbox. *
23 * The file COPYING for the complete GNU General Public License. *
24 * *
25 * You can reach me by (preferably e-mail): *
26 * *
27 * Rene' Jager *
28 * *
29 * Delft University of Technology *
30 * Department of Electrical Engineering *
31 * Control Laboratory *
32 * *
33 * Room ET 12.06 *
34 * *
35 * Mekelweg 4 *
36 * P.O.Box 5031 *
37 * 2600 GA Delft *
38 * The Netherlands *
39 * *
40 * e-mail: R.Jager@ET.TUDelft.NL *
41 * phone: +31-15-78 51 14 *
42 * fax: +31-15-62 67 38 *
43 * telex: 38151 butud nl *
44 * *
45 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
48 File: infer.c
49 Author: Rene' Jager
50 Update: January 4, 1993
51 Info: source file for RICE
55 /* hidden include files */
57 #include "include.h"
58 #include "define.h"
59 #include "type.h"
60 #include "function.h"
61 #include "variable.h"
64 /* macro for swapping */
66 #define SwapIndices(ind1,ind2) \
67 { \
68 int __ind; \
69 Protect(1); \
70 __ind = ind1; \
71 ind1 = ind2; \
72 ind2 = __ind; \
73 Protect(0); \
77 /* prototypes of static functions */
79 PROTOTYPE(static int KnownCondition, (OBJ_CONDITION *));
80 PROTOTYPE(static int KnownRule, (OBJ_RULE *));
81 PROTOTYPE(static int KnownDimension, (OBJ_DIMENSION *));
82 PROTOTYPE(static int RelationTarget, (OBJ_RELATION *));
84 PROTOTYPE(static void EvaluateCondition, (OBJ_CONDITION *, float *, int));
85 PROTOTYPE(static void EvaluateDimension, (OBJ_DIMENSION *, float *, int));
86 PROTOTYPE(static void ExecuteAction, (OBJ_ACTION *, float *));
87 PROTOTYPE(static void ExecuteDimension, (OBJ_DIMENSION *, float *));
88 PROTOTYPE(static void InferBase, (OBJ_BASE *));
89 PROTOTYPE(static void InferLayer, (OBJ_LAYER *));
90 PROTOTYPE(static void InferFact, (OBJ_FACT *));
91 PROTOTYPE(static void ApplyRule, (OBJ_RULE *));
92 PROTOTYPE(static void ApplyRelation, (OBJ_RELATION *, int));
93 PROTOTYPE(static void AskFact, (OBJ_FACT *, int, char *[]));
94 PROTOTYPE(static void InformFact, (OBJ_FACT *, int, char *[]));
95 PROTOTYPE(static void RunFact, (OBJ_FACT *, int, char *[]));
98 /* main infer-funtion */
100 FUNCTION(int InferKB,
101 (int index),
102 (index),
103 int index;
106 if(SwitchES(index))
107 return -1;
109 if(!objectList)
110 return -1;
112 InferBase(IDX2BAS(0));
114 return 0;
118 /* static infer-functions */
120 FUNCTION(static void InferBase,
121 (OBJ_BASE *base),
122 (base),
123 OBJ_BASE *base;
126 register int i, j;
127 OBJ_LAYER *layer;
129 for(i = 1; i <= base->layer[0]; i++)
131 layer = IDX2LAY(base->layer[i]);
133 for(j = 1; j <= layer->rule[0]; j++)
134 IDX2RUL(layer->rule[j])->slot.FIREABLE = 0;
136 for(j = 1; j <= layer->relation[0]; j++)
137 IDX2REL(layer->relation[j])->slot.FIREABLE = 0;
140 for(i = 1; i <= base->layer[0]; i++)
141 if(IDX2OBJ(base->layer[i])->status.ACTIVE)
142 InferLayer(IDX2LAY(base->layer[i]));
146 FUNCTION(static void InferLayer,
147 (OBJ_LAYER *layer),
148 (layer),
149 OBJ_LAYER *layer;
152 register int i;
153 OBJ_FACT *fact;
154 OBJ_RULE *rule;
155 OBJ_RELATION *relation;
156 int target, fired;
157 float grade = GRD_TRUE;
159 /* do all initial actions */
160 for(i = 1; i <= layer->init[0]; i++)
161 ExecuteAction(IDX2ACT(layer->init[i]), &grade);
163 /* in case of forward reasoning, get all data from previous layers */
164 if(layer->slot.FORWARD)
166 for(i = 1; i <= layer->data[0]; i++)
168 fact = IDX2FAC(layer->data[i]);
170 InferFact(fact);
172 /* fact must be known before inferring layer */
173 if(fact->grade == GRD_UNKNOWN)
175 if(fact->slot.CODE)
176 RunFact(fact, 1, &fact->symbolic);
177 else
178 AskFact(fact, 1, &fact->symbolic);
183 /* release all rules and relations in this layer */
184 for(i = 1; i <= layer->rule[0]; i++)
185 IDX2RUL(layer->rule[i])->slot.FIREABLE = 1;
187 for(i = 1; i <= layer->relation[0]; i++)
188 IDX2REL(layer->relation[i])->slot.FIREABLE = 1;
190 /* breadth-first forward reasoning */
191 if(layer->slot.FORWARD)
195 fired = 0;
197 for(i = 1; i <= layer->rule[0]; i++)
199 rule = IDX2RUL(layer->rule[i]);
201 if(rule->status.ACTIVE && rule->slot.FIREABLE && !rule->slot.FIRED)
202 if(KnownRule(rule))
204 ApplyRule(rule);
205 fired = 1;
209 for(i = 1; i <= layer->relation[0]; i++)
211 relation = IDX2REL(layer->relation[i]);
213 if(relation->status.ACTIVE && relation->slot.FIREABLE && !relation->slot.FIRED)
214 if((target = RelationTarget(relation)))
216 ApplyRelation(relation, target);
217 fired = 1;
221 while(fired);
224 /* depth-first backward reasoning */
225 if(layer->slot.BACKWARD)
227 for(i = 1; i <= layer->goal[0]; i++)
229 fact = IDX2FAC(layer->goal[i]);
231 InferFact(fact);
233 if(fact->grade == GRD_UNKNOWN)
235 if(fact->slot.CODE)
236 RunFact(fact, 1, &fact->symbolic);
237 elif(interactiveMode)
238 AskFact(fact, 1, &fact->symbolic);
245 FUNCTION(static void InferFact,
246 (OBJ_FACT *fact),
247 (fact),
248 OBJ_FACT *fact;
251 register int i;
253 /* if fact is already being inferred */
254 if(fact->slot.INFERRING)
255 return;
257 fact->slot.INFERRING = 1;
259 if(fact->grade == GRD_UNKNOWN)
261 for(i = 1; i <= fact->backward[0]; i++)
263 switch(IDX2OBJ(fact->backward[i])->type)
265 case TYP_RULE:
266 if(IDX2RUL(fact->backward[i])->slot.FIREABLE)
267 if(IDX2RUL(fact->backward[i])->status.ACTIVE)
268 ApplyRule(IDX2RUL(fact->backward[i]));
269 break;
271 case TYP_RELATION:
272 if(IDX2REL(fact->backward[i])->slot.FIREABLE)
273 if(IDX2REL(fact->backward[i])->status.ACTIVE)
274 ApplyRelation(IDX2REL(fact->backward[i]), fact->number);
275 break;
277 default:
278 Report(MSG_ERROR, MSG_BUG_INTERNAL);
279 Abandon();
280 break;
285 fact->slot.INFERRING = 0;
289 /* help-functions */
291 FUNCTION(static void ApplyRule,
292 (OBJ_RULE *rule),
293 (rule),
294 OBJ_RULE *rule;
297 register int i;
298 OBJ_CONDITION *condition;
299 float grade = GRD_UNKNOWN, degree;
301 if((rule->slot.FIRED || rule->slot.FIRING) && !recursiveMode)
302 return;
304 rule->slot.FIRING = 1;
306 if(rule->slot.INTERSECTION)
308 grade = GRD_TRUE;
310 for(i = 1; i <= rule->condition[0]; i++)
312 condition = IDX2CON(rule->condition[i]);
314 if(condition->status.ACTIVE)
315 EvaluateCondition(condition, &degree, MOD_DEPTH);
316 else
317 degree = GRD_TRUE;
319 grade = (*condition->norm)(grade, degree);
321 if(grade == GRD_FALSE)
323 if(selectiveMode && i > 1 && !condition->slot.IF)
324 if(!IDX2CON(rule->condition[i-1])->slot.IF)
325 SwapIndices(rule->condition[i], rule->condition[i-1]);
327 break;
331 elif(rule->slot.UNION)
333 grade = GRD_FALSE;
335 for(i = 1; i <= rule->condition[0]; i++)
337 condition = IDX2CON(rule->condition[i]);
339 if(condition->status.ACTIVE)
340 EvaluateCondition(condition, &degree, MOD_DEPTH);
341 else
342 degree = GRD_FALSE;
344 grade = (*condition->norm)(grade, degree);
346 if(grade == GRD_TRUE)
348 if(selectiveMode && i > 1 && !condition->slot.IF)
349 if(!IDX2CON(rule->condition[i-1])->slot.IF)
350 SwapIndices(rule->condition[i], rule->condition[i-1]);
352 break;
357 /* grade should have usable value */
358 if(grade != GRD_UNKNOWN)
360 for(i = 1; i <= rule->action[0]; i++)
362 /* action should be active */
363 if(IDX2ACT(rule->action[i])->status.ACTIVE && grade != GRD_UNKNOWN)
364 ExecuteAction(IDX2ACT(rule->action[i]), &grade);
368 rule->slot.FIRED = 1;
369 rule->slot.FIRING = 0;
373 FUNCTION(static int KnownCondition,
374 (OBJ_CONDITION *condition),
375 (condition),
376 OBJ_CONDITION *condition;
379 /* condition object should be a fact */
380 if(condition->slot.FAC)
382 /* nothing to be inferred */
383 if(condition->slot.ON || condition->slot.OFF)
384 return 1;
386 /* in case of arguments always unknown */
387 if(condition->argc > 1)
388 return 0;
390 /* run or ask perform in repetitive mode */
391 if((condition->slot.RUN || condition->slot.USR) && repetitiveMode)
392 return 0;
394 /* just an unknown fact */
395 if(IDX2FAC(condition->object)->grade == GRD_UNKNOWN)
396 return 0;
399 return 1;
403 FUNCTION(static int KnownRule,
404 (OBJ_RULE *rule),
405 (rule),
406 OBJ_RULE *rule;
409 register int i;
410 int known;
412 if(rule->slot.INTERSECTION)
414 /* false condition is sufficient */
415 for(i = 1, known = 1; i <= rule->condition[0]; i++)
416 if(!KnownCondition(IDX2CON(rule->condition[i])))
417 known = 0;
418 else
419 if(IDX2FAC(IDX2CON(rule->condition[i])->object)->grade == GRD_FALSE)
420 return 1;
422 if(known)
423 return 1;
425 elif(rule->slot.UNION)
427 /* true condition is sufficient */
428 for(i = 1, known = 1; i <= rule->condition[0]; i++)
429 if(!KnownCondition(IDX2CON(rule->condition[i])))
430 known = 0;
431 else
432 if(IDX2FAC(IDX2CON(rule->condition[i])->object)->grade == GRD_TRUE)
433 return 1;
435 if(known)
436 return 1;
439 return 0;
443 FUNCTION(static void EvaluateCondition,
444 (OBJ_CONDITION *condition, float *grade, int mode),
445 (condition, grade, mode),
446 OBJ_CONDITION *condition;
447 float *grade;
448 int mode;
451 float degree = GRD_UNKNOWN;
453 if(condition->slot.ON)
454 degree = IDX2OBJ(condition->object)->status.ACTIVE ? GRD_TRUE : GRD_FALSE;
455 elif(condition->slot.OFF)
456 degree = IDX2OBJ(condition->object)->status.ACTIVE ? GRD_FALSE : GRD_TRUE;
457 elif(condition->slot.FAC)
459 OBJ_FACT *fact;
461 fact = IDX2FAC(condition->object);
463 if(mode == MOD_DEPTH)
465 if(condition->slot.RUN)
467 if(repetitiveMode || fact->grade == GRD_UNKNOWN || condition->argc > 1)
469 RunFact(fact, condition->argc, condition->argv);
470 degree = fact->grade;
472 /* arguments make it temporal */
473 if(condition->argc > 1)
474 fact->grade = GRD_UNKNOWN;
477 elif(condition->slot.USR)
479 if(repetitiveMode || fact->grade == GRD_UNKNOWN || condition->argc > 1)
481 AskFact(fact, condition->argc, condition->argv);
482 degree = fact->grade;
484 /* arguments make it temporal */
485 if(condition->argc > 1)
486 fact->grade = GRD_UNKNOWN;
489 else
491 /* explaination */
492 if(condition->slot.SHW)
493 WhyFact(fact, -1);
495 if(fact->grade == GRD_UNKNOWN)
496 InferFact(fact);
498 if(fact->grade == GRD_UNKNOWN)
500 if(fact->slot.CODE)
501 RunFact(fact, condition->argc, condition->argv);
502 elif(interactiveMode)
503 AskFact(fact, condition->argc, condition->argv);
505 degree = fact->grade;
507 /* arguments make it temporal */
508 if(condition->argc > 1)
509 fact->grade = GRD_UNKNOWN;
511 else
512 degree = fact->grade;
515 else
516 degree = fact->grade;
518 elif(condition->slot.LAY)
520 OBJ_LAYER *layer;
522 layer = IDX2LAY(condition->object);
524 if(condition->slot.BKW)
525 degree = layer->slot.BACKWARD ? GRD_TRUE : GRD_FALSE;
526 elif(condition->slot.FRW)
527 degree = layer->slot.FORWARD ? GRD_TRUE : GRD_FALSE;
529 elif(condition->slot.CON)
531 OBJ_CONDITION *condition2;
533 condition2 = IDX2CON(condition->object);
535 if(condition->slot.CUT)
536 degree = condition2->level;
538 elif(condition->slot.ACT)
540 OBJ_ACTION *action;
542 action = IDX2ACT(condition->object);
544 if(condition->slot.GRD)
545 degree = action->grade;
546 elif(condition->slot.CUT)
547 degree = action->level;
549 elif(condition->slot.DIM)
551 OBJ_DIMENSION *dimension;
553 dimension = IDX2DIM(condition->object);
555 if(condition->slot.GRD)
556 degree = dimension->grade;
557 elif(condition->slot.CUT)
558 degree = dimension->level;
561 if(condition->slot.NOT)
562 degree = FNOT(degree);
564 condition->truth = *grade = FCUT(degree, condition->level);
568 FUNCTION(static void ExecuteAction,
569 (OBJ_ACTION *action, float *grade),
570 (action, grade),
571 OBJ_ACTION *action;
572 float *grade;
575 float degree = *grade;
577 if(action->slot.THEN && degree < action->level)
578 return;
580 if(action->slot.ELSE && degree > action->level)
581 return;
583 if(action->slot.ELSE)
584 degree = FNOT(degree);
586 if(action->slot.NOT)
587 degree = FNOT(degree);
589 action->truth = degree = (*action->norm)(action->grade, degree);
591 if(action->slot.ON || action->slot.OFF)
593 /* activate in case of ON flag */
594 IDX2OBJ(action->object)->status.ACTIVE =
595 (!action->slot.NOT && action->slot.ON) ||
596 (action->slot.NOT && action->slot.OFF);
598 /* also (in)activate rules and relations of layers */
599 if(action->slot.LAY)
601 register int i;
602 OBJ_LAYER *layer = IDX2LAY(action->object);
604 for(i = 1; i <= layer->rule[0]; i++)
605 IDX2RUL(layer->rule[i])->status.ACTIVE = layer->status.ACTIVE;
607 for(i = 1; i <= layer->relation[0]; i++)
608 IDX2RUL(layer->relation[i])->status.ACTIVE = layer->status.ACTIVE;
611 elif(action->slot.FAC)
613 OBJ_FACT *fact;
615 fact = IDX2FAC(action->object);
617 /* run or inform if trivial, assign degree as temporal */
618 if(action->slot.RUN || (action->argc > 1 && IDX2FAC(action->object)->slot.CODE))
620 fact->grade = degree;
621 RunFact(fact, action->argc, action->argv);
623 /* grade is temporal in case of arguments */
624 if(action->argc > 1)
625 fact->grade = GRD_UNKNOWN;
627 elif(action->slot.USR || (action->argc > 1 && !IDX2FAC(action->object)->slot.CODE))
629 fact->grade = degree;
630 InformFact(fact, action->argc, action->argv);
632 /* grade is temporal in case of arguments */
633 if(action->argc > 1)
634 fact->grade = GRD_UNKNOWN;
636 elif(action->slot.SHW)
638 fact->grade = degree;
639 HowFact(fact, -1);
641 /* grade is temporal in case of arguments */
642 if(action->argc > 1)
643 fact->grade = GRD_UNKNOWN;
645 else
647 /* when not an init take average when multiple concluded */
648 if(action->slot.INIT)
649 fact->grade = degree;
650 else
651 fact->grade = (fact->sumgrade += degree)/(fact->numgrade += 1);
654 elif(action->slot.LAY)
656 OBJ_LAYER *layer;
658 layer = IDX2LAY(action->object);
660 if(action->slot.BKW)
661 layer->slot.BACKWARD = (action->slot.NOT ? 0 : 1);
662 elif(action->slot.FRW)
663 layer->slot.FORWARD = (action->slot.NOT ? 0 : 1);
664 elif(action->slot.INV)
665 InferLayer(OBJ2LAY(objectList[action->object]));
667 elif(action->slot.CON)
669 OBJ_CONDITION *condition;
671 condition = IDX2CON(action->object);
673 if(action->slot.CUT)
674 condition->level = degree;
676 elif(action->slot.ACT)
678 OBJ_ACTION *action2;
680 action2 = IDX2ACT(action->object);
682 if(action->slot.GRD)
683 action2->grade = degree;
684 elif(action->slot.CUT)
685 action2->level = degree;
687 elif(action->slot.DIM)
689 OBJ_DIMENSION *dimension;
691 dimension = IDX2DIM(action->object);
693 if(action->slot.GRD)
694 dimension->grade = degree;
695 elif(action->slot.CUT)
696 dimension->level = degree;
701 FUNCTION(static int KnownDimension,
702 (OBJ_DIMENSION *dimension),
703 (dimension),
704 OBJ_DIMENSION *dimension;
707 /* unknown object can only be a fact */
708 if(dimension->slot.FAC)
710 /* always unknown in case of arguments */
711 if(dimension->argc > 1)
712 return 0;
714 /* perforn run or ask in repetitive mode */
715 if((dimension->slot.RUN || dimension->slot.USR) && repetitiveMode)
716 return 0;
718 /* just an unknown fact */
719 if(IDX2FAC(dimension->object)->grade == GRD_UNKNOWN)
720 return 0;
723 return 1;
727 FUNCTION(static int RelationTarget,
728 (OBJ_RELATION *relation),
729 (relation),
730 OBJ_RELATION *relation;
733 register int i;
734 int target = 0;
736 for(i = 1; i <= relation->dimension[0]; i++)
738 if(!KnownDimension(IDX2DIM(relation->dimension[i])))
740 if(target)
741 return 0;
742 else
743 target = IDX2DIM(relation->dimension[i])->object;
747 return target;
751 FUNCTION(static void ApplyRelation,
752 (OBJ_RELATION *relation, int target),
753 (relation, target),
754 OBJ_RELATION *relation;
755 int target;
758 register int i;
759 OBJ_DIMENSION *dimension, *output = 0;
760 float grade, degree;
762 if(!relation->status.ACTIVE)
763 return;
765 if((relation->slot.FIRED || relation->slot.FIRING) && !recursiveMode)
766 return;
768 relation->slot.FIRING = 1;
770 if(relation->dimension[0] > 1)
771 grade = GRD_TRUE;
772 else
773 grade = GRD_UNKNOWN;
775 for(i = 1; i <= relation->dimension[0]; i++)
777 dimension = IDX2DIM(relation->dimension[i]);
779 if(dimension->object != target)
781 if(dimension->status.ACTIVE)
782 EvaluateDimension(dimension, &degree, MOD_DEPTH);
783 else
784 degree = GRD_TRUE;
786 grade = (*dimension->norm)(grade, degree);
788 if(grade == GRD_FALSE)
790 if(selectiveMode && i > 1)
791 SwapIndices(relation->dimension[i], relation->dimension[i-1]);
793 break;
796 else
797 output = dimension;
799 if(grade == GRD_FALSE)
800 break;
803 if(!output) /* quickly find target dimension */
805 for(; i <= relation->dimension[0]; i++)
807 dimension = IDX2DIM(relation->dimension[i]);
809 if(dimension->object == target)
811 output = dimension;
812 break;
817 if(output->status.ACTIVE)
818 ExecuteDimension(output, &grade);
820 relation->slot.FIRED = 1;
821 relation->slot.FIRING = 0;
825 FUNCTION(static void EvaluateDimension,
826 (OBJ_DIMENSION *dimension, float *grade, int mode),
827 (dimension, grade, mode),
828 OBJ_DIMENSION *dimension;
829 float *grade;
830 int mode;
833 float degree = GRD_UNKNOWN;
835 if(dimension->slot.ON)
836 degree = IDX2OBJ(dimension->object)->status.ACTIVE ? GRD_TRUE : GRD_FALSE;
837 elif(dimension->slot.OFF)
838 degree = IDX2OBJ(dimension->object)->status.ACTIVE ? GRD_FALSE : GRD_TRUE;
839 elif(dimension->slot.FAC)
841 OBJ_FACT *fact;
843 fact = IDX2FAC(dimension->object);
845 if(mode == MOD_DEPTH)
847 if(dimension->slot.RUN)
849 if(repetitiveMode || fact->grade == GRD_UNKNOWN || dimension->argc > 1)
851 RunFact(fact, dimension->argc, dimension->argv);
852 degree = fact->grade;
853 if(dimension->argc > 1) /* reset because of arguments */
854 fact->grade = GRD_UNKNOWN;
857 elif(dimension->slot.USR)
859 if(repetitiveMode || fact->grade == GRD_UNKNOWN || dimension->argc > 1)
861 AskFact(fact, dimension->argc, dimension->argv);
862 degree = fact->grade;
863 if(dimension->argc > 1) /* reset because of arguments */
864 fact->grade = GRD_UNKNOWN;
867 else
869 /* explaination */
870 if(dimension->slot.SHW)
871 WhyFact(fact, -1);
873 if(fact->grade == GRD_UNKNOWN)
874 InferFact(fact);
876 if(fact->grade == GRD_UNKNOWN)
878 if(fact->slot.CODE)
879 RunFact(fact, dimension->argc, dimension->argv);
880 elif(interactiveMode)
881 AskFact(fact, dimension->argc, dimension->argv);
883 degree = fact->grade;
885 if(dimension->argc > 1)
886 fact->grade = GRD_UNKNOWN; /* reset due to arguments */
888 else
889 degree = fact->grade;
892 else
893 degree = fact->grade;
895 elif(dimension->slot.LAY)
897 OBJ_LAYER *layer;
899 layer = IDX2LAY(dimension->object);
901 if(dimension->slot.BKW)
902 degree = layer->slot.BACKWARD ? GRD_TRUE : GRD_FALSE;
903 elif(dimension->slot.FRW)
904 degree = layer->slot.FORWARD ? GRD_TRUE : GRD_FALSE;
906 elif(dimension->slot.CON)
908 OBJ_CONDITION *condition;
910 condition = IDX2CON(dimension->object);
912 if(dimension->slot.CUT)
913 degree = condition->level;
915 elif(dimension->slot.ACT)
917 OBJ_ACTION *action;
919 action = IDX2ACT(dimension->object);
921 if(dimension->slot.GRD)
922 degree = action->grade;
923 elif(dimension->slot.CUT)
924 degree = action->level;
926 elif(dimension->slot.DIM)
928 OBJ_DIMENSION *dimension2;
930 dimension2 = IDX2DIM(dimension->object);
932 if(dimension->slot.GRD)
933 degree = dimension2->grade;
934 elif(dimension->slot.CUT)
935 degree = dimension2->level;
938 if(dimension->slot.NOT)
939 degree = FNOT(degree);
941 dimension->truth[0] = *grade = FCUT(degree, dimension->level);
945 FUNCTION(static void ExecuteDimension,
946 (OBJ_DIMENSION *dimension, float *grade),
947 (dimension, grade),
948 OBJ_DIMENSION *dimension;
949 float *grade;
952 float degree = *grade;
954 if(degree < dimension->level)
955 return;
957 if(dimension->slot.NOT)
958 degree = FNOT(degree);
960 dimension->truth[1] = degree = (*dimension->norm)(dimension->grade, degree);
962 if(dimension->slot.ON || dimension->slot.OFF)
964 /* activate in case of ON flag */
965 IDX2OBJ(dimension->object)->status.ACTIVE =
966 (!dimension->slot.NOT && dimension->slot.ON) ||
967 (dimension->slot.NOT && dimension->slot.OFF);
969 /* also (in)activate rules and relations of layers */
970 if(dimension->slot.LAY)
972 register int i;
973 OBJ_LAYER *layer = IDX2LAY(dimension->object);
975 for(i = 1; i <= layer->rule[0]; i++)
976 IDX2RUL(layer->rule[i])->status.ACTIVE = layer->status.ACTIVE;
978 for(i = 1; i <= layer->relation[0]; i++)
979 IDX2RUL(layer->relation[i])->status.ACTIVE = layer->status.ACTIVE;
982 elif(dimension->slot.FAC)
984 OBJ_FACT *fact;
986 fact = IDX2FAC(dimension->object);
988 /* run or inform when trivial */
989 if(dimension->slot.RUN || (dimension->argc > 1 && fact->slot.CODE))
991 fact->grade = degree;
992 RunFact(fact, dimension->argc, dimension->argv);
994 /* grade is temporal in case of arguments */
995 if(dimension->argc > 1)
996 fact->grade = GRD_UNKNOWN;
998 elif(dimension->slot.USR || (dimension->argc > 1 && !fact->slot.CODE))
1000 fact->grade = degree;
1001 InformFact(fact, dimension->argc, dimension->argv);
1003 /* grade is temporal in case of arguments */
1004 if(dimension->argc > 1)
1005 fact->grade = GRD_UNKNOWN;
1007 elif(dimension->slot.SHW)
1009 fact->grade = degree;
1010 HowFact(fact, -1);
1012 /* grade is temporal in case of arguments */
1013 if(dimension->argc > 1)
1014 fact->grade = GRD_UNKNOWN;
1016 else
1018 /* take average when multiple concluded */
1019 fact->grade = (fact->sumgrade += degree)/(fact->numgrade += 1);
1022 elif(dimension->slot.LAY)
1024 OBJ_LAYER *layer;
1026 layer = IDX2LAY(dimension->object);
1028 if(dimension->slot.BKW)
1029 layer->slot.BACKWARD = (dimension->slot.NOT ? 0 : 1);
1030 elif(dimension->slot.FRW)
1031 layer->slot.FORWARD = (dimension->slot.NOT ? 0 : 1);
1033 elif(dimension->slot.CON)
1035 OBJ_CONDITION *condition;
1037 condition = IDX2CON(dimension->object);
1039 if(dimension->slot.CUT)
1040 condition->level = degree;
1042 elif(dimension->slot.ACT)
1044 OBJ_ACTION *action;
1046 action = IDX2ACT(dimension->object);
1048 if(dimension->slot.GRD)
1049 action->grade = degree;
1050 elif(dimension->slot.CUT)
1051 action->level = degree;
1053 elif(dimension->slot.DIM)
1055 OBJ_DIMENSION *dimension2;
1057 dimension2 = IDX2DIM(dimension->object);
1059 if(dimension->slot.GRD)
1060 dimension2->grade = degree;
1061 elif(dimension->slot.CUT)
1062 dimension2->level = degree;
1067 FUNCTION(static void AskFact,
1068 (OBJ_FACT *fact, int argc, char *argv[]),
1069 (fact, argc, argv),
1070 OBJ_FACT *fact;
1071 int argc;
1072 char *argv[];
1075 argv[0] = fact->symbolic;
1077 Ask(argc, argv, &fact->grade);
1081 FUNCTION(static void InformFact,
1082 (OBJ_FACT *fact, int argc, char *argv[]),
1083 (fact, argc, argv),
1084 OBJ_FACT *fact;
1085 int argc;
1086 char *argv[];
1089 float grade;
1091 grade = fact->grade;
1092 argv[0] = fact->symbolic;
1094 Inform(argc, argv, &grade);
1098 FUNCTION(static void RunFact,
1099 (OBJ_FACT *fact, int argc, char *argv[]),
1100 (fact, argc, argv),
1101 OBJ_FACT *fact;
1102 int argc;
1103 char *argv[];
1106 argv[0] = fact->symbolic;
1108 Run(fact->link, argc, argv, &fact->grade);
1110 if(fact->grade < GRD_FALSE || GRD_TRUE < fact->grade)
1111 fact->grade = GRD_UNKNOWN;