1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * RICE 4.0x Copyright (C) 1993 Rene' Jager *
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. *
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. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this toolbox; if not, write to the: *
18 * Free Software Foundation, Inc. *
19 * 675 Mass Ave, Cambridge *
22 * See the RICE documentation for more information on the toolbox. *
23 * The file COPYING for the complete GNU General Public License. *
25 * You can reach me by (preferably e-mail): *
29 * Delft University of Technology *
30 * Department of Electrical Engineering *
31 * Control Laboratory *
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 *
45 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
50 Update: January 4, 1993
51 Info: source file for RICE
55 /* hidden include files */
64 /* macro for swapping */
66 #define SwapIndices(ind1,ind2) \
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
,
112 InferBase(IDX2BAS(0));
118 /* static infer-functions */
120 FUNCTION(static void InferBase
,
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
,
155 OBJ_RELATION
*relation
;
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
]);
172 /* fact must be known before inferring layer */
173 if(fact
->grade
== GRD_UNKNOWN
)
176 RunFact(fact
, 1, &fact
->symbolic
);
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
)
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
)
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
);
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
]);
233 if(fact
->grade
== GRD_UNKNOWN
)
236 RunFact(fact
, 1, &fact
->symbolic
);
237 elif(interactiveMode
)
238 AskFact(fact
, 1, &fact
->symbolic
);
245 FUNCTION(static void InferFact
,
253 /* if fact is already being inferred */
254 if(fact
->slot
.INFERRING
)
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
)
266 if(IDX2RUL(fact
->backward
[i
])->slot
.FIREABLE
)
267 if(IDX2RUL(fact
->backward
[i
])->status
.ACTIVE
)
268 ApplyRule(IDX2RUL(fact
->backward
[i
]));
272 if(IDX2REL(fact
->backward
[i
])->slot
.FIREABLE
)
273 if(IDX2REL(fact
->backward
[i
])->status
.ACTIVE
)
274 ApplyRelation(IDX2REL(fact
->backward
[i
]), fact
->number
);
278 Report(MSG_ERROR
, MSG_BUG_INTERNAL
);
285 fact
->slot
.INFERRING
= 0;
291 FUNCTION(static void ApplyRule
,
298 OBJ_CONDITION
*condition
;
299 float grade
= GRD_UNKNOWN
, degree
;
301 if((rule
->slot
.FIRED
|| rule
->slot
.FIRING
) && !recursiveMode
)
304 rule
->slot
.FIRING
= 1;
306 if(rule
->slot
.INTERSECTION
)
310 for(i
= 1; i
<= rule
->condition
[0]; i
++)
312 condition
= IDX2CON(rule
->condition
[i
]);
314 if(condition
->status
.ACTIVE
)
315 EvaluateCondition(condition
, °ree
, MOD_DEPTH
);
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]);
331 elif(rule
->slot
.UNION
)
335 for(i
= 1; i
<= rule
->condition
[0]; i
++)
337 condition
= IDX2CON(rule
->condition
[i
]);
339 if(condition
->status
.ACTIVE
)
340 EvaluateCondition(condition
, °ree
, MOD_DEPTH
);
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]);
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
),
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
)
386 /* in case of arguments always unknown */
387 if(condition
->argc
> 1)
390 /* run or ask perform in repetitive mode */
391 if((condition
->slot
.RUN
|| condition
->slot
.USR
) && repetitiveMode
)
394 /* just an unknown fact */
395 if(IDX2FAC(condition
->object
)->grade
== GRD_UNKNOWN
)
403 FUNCTION(static int KnownRule
,
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
])))
419 if(IDX2FAC(IDX2CON(rule
->condition
[i
])->object
)->grade
== GRD_FALSE
)
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
])))
432 if(IDX2FAC(IDX2CON(rule
->condition
[i
])->object
)->grade
== GRD_TRUE
)
443 FUNCTION(static void EvaluateCondition
,
444 (OBJ_CONDITION
*condition
, float *grade
, int mode
),
445 (condition
, grade
, mode
),
446 OBJ_CONDITION
*condition
;
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
)
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
;
492 if(condition
->slot
.SHW
)
495 if(fact
->grade
== GRD_UNKNOWN
)
498 if(fact
->grade
== GRD_UNKNOWN
)
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
;
512 degree
= fact
->grade
;
516 degree
= fact
->grade
;
518 elif(condition
->slot
.LAY
)
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
)
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
),
575 float degree
= *grade
;
577 if(action
->slot
.THEN
&& degree
< action
->level
)
580 if(action
->slot
.ELSE
&& degree
> action
->level
)
583 if(action
->slot
.ELSE
)
584 degree
= FNOT(degree
);
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 */
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
)
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 */
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 */
634 fact
->grade
= GRD_UNKNOWN
;
636 elif(action
->slot
.SHW
)
638 fact
->grade
= degree
;
641 /* grade is temporal in case of arguments */
643 fact
->grade
= GRD_UNKNOWN
;
647 /* when not an init take average when multiple concluded */
648 if(action
->slot
.INIT
)
649 fact
->grade
= degree
;
651 fact
->grade
= (fact
->sumgrade
+= degree
)/(fact
->numgrade
+= 1);
654 elif(action
->slot
.LAY
)
658 layer
= IDX2LAY(action
->object
);
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
);
674 condition
->level
= degree
;
676 elif(action
->slot
.ACT
)
680 action2
= IDX2ACT(action
->object
);
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
);
694 dimension
->grade
= degree
;
695 elif(action
->slot
.CUT
)
696 dimension
->level
= degree
;
701 FUNCTION(static int KnownDimension
,
702 (OBJ_DIMENSION
*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)
714 /* perforn run or ask in repetitive mode */
715 if((dimension
->slot
.RUN
|| dimension
->slot
.USR
) && repetitiveMode
)
718 /* just an unknown fact */
719 if(IDX2FAC(dimension
->object
)->grade
== GRD_UNKNOWN
)
727 FUNCTION(static int RelationTarget
,
728 (OBJ_RELATION
*relation
),
730 OBJ_RELATION
*relation
;
736 for(i
= 1; i
<= relation
->dimension
[0]; i
++)
738 if(!KnownDimension(IDX2DIM(relation
->dimension
[i
])))
743 target
= IDX2DIM(relation
->dimension
[i
])->object
;
751 FUNCTION(static void ApplyRelation
,
752 (OBJ_RELATION
*relation
, int target
),
754 OBJ_RELATION
*relation
;
759 OBJ_DIMENSION
*dimension
, *output
= 0;
762 if(!relation
->status
.ACTIVE
)
765 if((relation
->slot
.FIRED
|| relation
->slot
.FIRING
) && !recursiveMode
)
768 relation
->slot
.FIRING
= 1;
770 if(relation
->dimension
[0] > 1)
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
, °ree
, MOD_DEPTH
);
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]);
799 if(grade
== GRD_FALSE
)
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
)
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
;
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
)
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
;
870 if(dimension
->slot
.SHW
)
873 if(fact
->grade
== GRD_UNKNOWN
)
876 if(fact
->grade
== GRD_UNKNOWN
)
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 */
889 degree
= fact
->grade
;
893 degree
= fact
->grade
;
895 elif(dimension
->slot
.LAY
)
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
)
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
),
948 OBJ_DIMENSION
*dimension
;
952 float degree
= *grade
;
954 if(degree
< dimension
->level
)
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
)
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
)
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
;
1012 /* grade is temporal in case of arguments */
1013 if(dimension
->argc
> 1)
1014 fact
->grade
= GRD_UNKNOWN
;
1018 /* take average when multiple concluded */
1019 fact
->grade
= (fact
->sumgrade
+= degree
)/(fact
->numgrade
+= 1);
1022 elif(dimension
->slot
.LAY
)
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
)
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
[]),
1075 argv
[0] = fact
->symbolic
;
1077 Ask(argc
, argv
, &fact
->grade
);
1081 FUNCTION(static void InformFact
,
1082 (OBJ_FACT
*fact
, int argc
, char *argv
[]),
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
[]),
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
;