45 #define DEBUG DEBUG_NONE
55 #ifndef LVM_MAX_NAME_LENGTH
56 #define LVM_MAX_NAME_LENGTH 16
59 #ifndef LVM_MAX_VARIABLE_ID
60 #define LVM_MAX_VARIABLE_ID 8
63 #ifndef LVM_USE_FLOATS
64 #define LVM_USE_FLOATS 0
67 #define IS_CONNECTIVE(op) ((op) & LVM_CONNECTIVE)
71 operand_value_t value;
72 char name[LVM_MAX_NAME_LENGTH + 1];
74 typedef struct variable variable_t;
81 typedef struct derivation derivation_t;
85 static variable_t variables[LVM_MAX_VARIABLE_ID - 1];
88 static derivation_t derivations[LVM_MAX_VARIABLE_ID - 1];
92 print_derivations(derivation_t *d)
96 for(i = 0; i < LVM_MAX_VARIABLE_ID; i++) {
98 printf(
"%s is constrained to (%ld,%ld)\n", variables[i].name,
99 d[i].min.l, d[i].max.l);
110 for(var = variables; var <= &variables[LVM_MAX_VARIABLE_ID - 1] && var->name[0] !=
'\0'; var++) {
111 if(strcmp(var->name, name) == 0) {
116 return (variable_id_t)(var - &variables[0]);
120 get_operator(lvm_instance_t *p)
122 operator_t *
operator;
124 operator = (operator_t *)&p->code[p->ip];
125 p->ip +=
sizeof(operator_t);
130 get_operand(lvm_instance_t *p, operand_t *operand)
132 memcpy(operand, &p->code[p->ip],
sizeof(*operand));
133 p->ip +=
sizeof(*operand);
137 get_type(lvm_instance_t *p)
139 node_type_t node_type;
141 node_type = *(node_type_t *)(p->code + p->ip);
142 p->ip +=
sizeof(node_type);
148 operand_to_long(operand_t *operand)
150 switch(operand->type) {
152 return operand->value.l;
155 return (
long)operand->value.f;
159 return variables[operand->value.id].value.l;
166 eval_expr(lvm_instance_t *p, operator_t op, operand_t *result)
170 operator_t *
operator;
171 operand_t operand[2];
176 for(i = 0; i < 2; i++) {
180 operator = get_operator(p);
181 r = eval_expr(p, *
operator, &operand[i]);
187 get_operand(p, &operand[i]);
190 return SEMANTIC_ERROR;
192 value[i] = operand_to_long(&operand[i]);
197 result_value = value[0] + value[1];
200 result_value = value[0] - value[1];
203 result_value = value[0] * value[1];
209 result_value = value[0] / value[1];
212 return EXECUTION_ERROR;
215 result->type = LVM_LONG;
216 result->value.l = result_value;
222 eval_logic(lvm_instance_t *p, operator_t *op)
229 operator_t *
operator;
234 if(IS_CONNECTIVE(*op)) {
235 arguments = *op == LVM_NOT ? 1 : 2;
236 for(i = 0; i < arguments; i++) {
238 if(type != LVM_CMP_OP) {
239 return SEMANTIC_ERROR;
241 operator = get_operator(p);
242 logic_result[i] = eval_logic(p,
operator);
243 if(LVM_ERROR(logic_result[i])) {
244 return logic_result[i];
249 return !logic_result[0];
250 }
else if(*op == LVM_AND) {
251 return logic_result[0] ==
TRUE && logic_result[1] ==
TRUE;
253 return logic_result[0] ==
TRUE || logic_result[1] ==
TRUE;
257 for(i = 0; i < 2; i++) {
261 operator = get_operator(p);
262 r = eval_expr(p, *
operator, &operand);
268 get_operand(p, &operand);
271 return SEMANTIC_ERROR;
273 result[i] = operand_to_long(&operand);
278 PRINTF(
"Result1: %ld\nResult2: %ld\n", l1, l2);
297 return EXECUTION_ERROR;
301 lvm_reset(lvm_instance_t *p,
unsigned char *code, lvm_ip_t size)
303 memset(code, 0, size);
310 memset(variables, 0,
sizeof(variables));
311 memset(derivations, 0,
sizeof(derivations));
315 lvm_jump_to_operand(lvm_instance_t *p)
320 p->end +=
sizeof(operator_t) +
sizeof(node_type_t);
321 if(p->end >= p->size) {
330 lvm_shift_for_operator(lvm_instance_t *p, lvm_ip_t end)
337 if(p->end +
sizeof(operator_t) > p->size || end >= old_end) {
344 memmove(ptr +
sizeof(operator_t) +
sizeof(node_type_t), ptr, old_end - end);
347 return old_end +
sizeof(operator_t) +
sizeof(node_type_t);
351 lvm_get_end(lvm_instance_t *p)
357 lvm_set_end(lvm_instance_t *p, lvm_ip_t end)
373 lvm_set_type(lvm_instance_t *p, node_type_t type)
375 *(node_type_t *)(p->code + p->end) = type;
376 p->end +=
sizeof(type);
380 lvm_execute(lvm_instance_t *p)
383 operator_t *
operator;
387 status = EXECUTION_ERROR;
391 operator = get_operator(p);
392 status = eval_logic(p,
operator);
393 if(!LVM_ERROR(status)) {
394 PRINTF(
"The statement is %s\n", status ==
TRUE ?
"true" :
"false");
396 PRINTF(
"Execution error: %d\n", (
int)status);
400 PRINTF(
"Error: The code must start with a relational operator\n");
407 lvm_set_op(lvm_instance_t *p, operator_t op)
409 lvm_set_type(p, LVM_ARITH_OP);
410 memcpy(&p->code[p->end], &op,
sizeof(op));
411 p->end +=
sizeof(op);
415 lvm_set_relation(lvm_instance_t *p, operator_t op)
417 lvm_set_type(p, LVM_CMP_OP);
418 memcpy(&p->code[p->end], &op,
sizeof(op));
419 p->end +=
sizeof(op);
423 lvm_set_operand(lvm_instance_t *p, operand_t *op)
425 lvm_set_type(p, LVM_OPERAND);
426 memcpy(&p->code[p->end], op,
sizeof(*op));
427 p->end +=
sizeof(*op);
431 lvm_set_long(lvm_instance_t *p,
long l)
438 lvm_set_operand(p, &op);
442 lvm_register_variable(
char *name, operand_type_t type)
448 if(
id == LVM_MAX_VARIABLE_ID) {
449 return VARIABLE_LIMIT_REACHED;
452 var = &variables[id];
453 if(var->name[0] ==
'\0') {
454 strncpy(var->name, name,
sizeof(var->name) - 1);
455 var->name[
sizeof(var->name) - 1] =
'\0';
463 lvm_set_variable_value(
char *name, operand_value_t value)
468 if(
id == LVM_MAX_VARIABLE_ID) {
469 return INVALID_IDENTIFIER;
471 variables[id].value = value;
476 lvm_set_variable(lvm_instance_t *p,
char *name)
482 if(
id < LVM_MAX_VARIABLE_ID) {
483 PRINTF(
"var id = %d\n",
id);
484 op.type = LVM_VARIABLE;
486 lvm_set_operand(p, &op);
491 lvm_clone(lvm_instance_t *dst, lvm_instance_t *src)
493 memcpy(dst, src,
sizeof(*dst));
497 create_intersection(derivation_t *result, derivation_t *d1, derivation_t *d2)
501 for(i = 0; i < LVM_MAX_VARIABLE_ID; i++) {
502 if(!d1[i].derived && !d2[i].derived) {
504 }
else if(d1[i].derived && !d2[i].derived) {
505 result[i].min.l = d1[i].min.l;
506 result[i].max.l = d1[i].max.l;
507 }
else if(!d1[i].derived && d2[i].derived) {
508 result[i].min.l = d2[i].min.l;
509 result[i].max.l = d2[i].max.l;
513 if(d1[i].min.l > d2[i].min.l) {
514 result[i].min.l = d1[i].min.l;
516 result[i].min.l = d2[i].min.l;
519 if(d1[i].max.l < d2[i].max.l) {
520 result[i].max.l = d1[i].max.l;
522 result[i].max.l = d2[i].max.l;
525 result[i].derived = 1;
529 PRINTF(
"Created an intersection of D1 and D2\n");
531 print_derivations(d1);
533 print_derivations(d2);
534 PRINTF(
"Result: \n");
535 print_derivations(result);
540 create_union(derivation_t *result, derivation_t *d1, derivation_t *d2)
544 for(i = 0; i < LVM_MAX_VARIABLE_ID; i++) {
545 if(!d1[i].derived && !d2[i].derived) {
547 }
else if(d1[i].derived && !d2[i].derived) {
548 result[i].min.l = d1[i].min.l;
549 result[i].max.l = d1[i].max.l;
550 }
else if(!d1[i].derived && d2[i].derived) {
551 result[i].min.l = d2[i].min.l;
552 result[i].max.l = d2[i].max.l;
556 if(d1[i].min.l > d2[i].min.l) {
557 result[i].min.l = d2[i].min.l;
559 result[i].min.l = d1[i].min.l;
562 if(d1[i].max.l < d2[i].max.l) {
563 result[i].max.l = d2[i].max.l;
565 result[i].max.l = d1[i].max.l;
568 result[i].derived = 1;
572 PRINTF(
"Created a union of D1 and D2\n");
574 print_derivations(d1);
576 print_derivations(d2);
577 PRINTF(
"Result: \n");
578 print_derivations(result);
583 derive_relation(lvm_instance_t *p, derivation_t *local_derivations)
585 operator_t *
operator;
587 operand_t operand[2];
590 operand_value_t *value;
591 derivation_t *derivation;
594 operator = get_operator(p);
596 if(IS_CONNECTIVE(*
operator)) {
597 derivation_t d1[LVM_MAX_VARIABLE_ID];
598 derivation_t d2[LVM_MAX_VARIABLE_ID];
600 if(*
operator != LVM_AND && *
operator != LVM_OR) {
601 return DERIVATION_ERROR;
604 PRINTF(
"Attempting to infer ranges from a logical connective\n");
606 memset(d1, 0,
sizeof(d1));
607 memset(d2, 0,
sizeof(d2));
609 if(LVM_ERROR(derive_relation(p, d1)) ||
610 LVM_ERROR(derive_relation(p, d2))) {
611 return DERIVATION_ERROR;
614 if(*
operator == LVM_AND) {
615 create_intersection(local_derivations, d1, d2);
616 }
else if(*
operator == LVM_OR) {
617 create_union(local_derivations, d1, d2);
622 for(i = 0; i < 2; i++) {
626 get_operand(p, &operand[i]);
629 return DERIVATION_ERROR;
633 if(operand[0].type == LVM_VARIABLE && operand[1].type == LVM_VARIABLE) {
634 return DERIVATION_ERROR;
638 if(operand[0].type == LVM_VARIABLE) {
639 if(operand[1].type == LVM_VARIABLE) {
640 return DERIVATION_ERROR;
642 variable_id = operand[0].value.id;
643 value = &operand[1].value;
645 variable_id = operand[1].value.id;
646 value = &operand[0].value;
649 if(variable_id >= LVM_MAX_VARIABLE_ID) {
650 return DERIVATION_ERROR;
653 PRINTF(
"variable id %d, value %ld\n", variable_id, *(
long *)value);
655 derivation = local_derivations + variable_id;
657 derivation->max.l = LONG_MAX;
658 derivation->min.l = LONG_MIN;
662 derivation->max = *value;
663 derivation->min = *value;
666 derivation->min.l = value->l + 1;
669 derivation->min.l = value->l;
672 derivation->max.l = value->l - 1;
675 derivation->max.l = value->l;
678 return DERIVATION_ERROR;
681 derivation->derived = 1;
687 lvm_derive(lvm_instance_t *p)
689 return derive_relation(p, derivations);
693 lvm_get_derived_range(lvm_instance_t *p,
char *name,
694 operand_value_t *min, operand_value_t *max)
698 for(i = 0; i < LVM_MAX_VARIABLE_ID; i++) {
699 if(strcmp(name, variables[i].name) == 0) {
700 if(derivations[i].derived) {
701 *min = derivations[i].min;
702 *max = derivations[i].max;
705 return DERIVATION_ERROR;
708 return INVALID_IDENTIFIER;
713 print_operator(lvm_instance_t *p, lvm_ip_t index)
716 struct operator_map {
718 char *representation;
720 struct operator_map operator_map[] = {
737 memcpy(&
operator, p->code + index,
sizeof(
operator));
739 for(i = 0; i <
sizeof(operator_map) /
sizeof(operator_map[0]); i++) {
740 if(operator_map[i].op ==
operator) {
741 PRINTF(
"%s ", operator_map[i].representation);
746 return index +
sizeof(operator_t);
750 print_operand(lvm_instance_t *p, lvm_ip_t index)
754 memcpy(&operand, p->code + index,
sizeof(operand));
756 switch(operand.type) {
758 if(operand.value.id >= LVM_MAX_VARIABLE_ID || variables[operand.value.id].name ==
NULL) {
759 PRINTF(
"var(id:%d):?? ", operand.value.id);
761 PRINTF(
"var(%s):%ld ", variables[operand.value.id].name,
762 variables[operand.value.id].value.l);
766 PRINTF(
"long:%ld ", operand.value.l);
773 return index +
sizeof(operand_t);
777 print_relation(lvm_instance_t *p, lvm_ip_t index)
780 return print_operator(p, index);
785 lvm_print_code(lvm_instance_t *p)
792 for(ip = 0; ip < p->end;) {
793 switch(*(node_type_t *)(p->code + ip)) {
795 ip = print_relation(p, ip +
sizeof(node_type_t));
798 ip = print_operator(p, ip +
sizeof(node_type_t));
801 ip = print_operand(p, ip +
sizeof(node_type_t));
804 PRINTF(
"Invalid opcode: 0x%x ", p->code[ip]);
814 lvm_print_derivations(lvm_instance_t *p)
817 print_derivations(derivations);
826 unsigned char code[256];
828 lvm_reset(&p, code,
sizeof(code));
830 lvm_register_variable(
"z", LVM_LONG);
831 lvm_set_variable_value(
"z", (operand_value_t)15L);
833 lvm_register_variable(
"y", LVM_LONG);
834 lvm_set_variable_value(
"y", (operand_value_t)109L);
837 lvm_set_relation(&p, LVM_AND);
838 lvm_set_relation(&p, LVM_EQ);
839 lvm_set_long(&p, 109);
840 lvm_set_variable(&p,
"y");
841 lvm_set_relation(&p, LVM_GE);
842 lvm_set_long(&p, 20);
843 lvm_set_op(&p, LVM_SUB);
844 lvm_set_long(&p, 70);
845 lvm_set_op(&p, LVM_ADD);
847 lvm_set_op(&p, LVM_MUL);
848 lvm_set_variable(&p,
"z");
856 lvm_reset(&p, code,
sizeof(code));
857 lvm_set_relation(&p, LVM_NOT);
858 lvm_set_relation(&p, LVM_LE);
859 lvm_set_op(&p, LVM_ADD);
860 lvm_set_long(&p, 9999);
862 lvm_set_op(&p, LVM_ADD);
863 lvm_set_long(&p, -1);
864 lvm_set_long(&p, 10001);
873 lvm_reset(&p, code,
sizeof(code));
874 lvm_register_variable(
"a", LVM_LONG);
875 lvm_set_relation(&p, LVM_EQ);
876 lvm_set_variable(&p,
"a");
880 lvm_print_derivations(&p);
883 lvm_reset(&p, code,
sizeof(code));
884 lvm_register_variable(
"a", LVM_LONG);
885 lvm_set_relation(&p, LVM_LE);
886 lvm_set_variable(&p,
"a");
887 lvm_set_long(&p, 10);
890 lvm_print_derivations(&p);
893 lvm_reset(&p, code,
sizeof(code));
894 lvm_register_variable(
"a", LVM_LONG);
895 lvm_set_relation(&p, LVM_AND);
896 lvm_set_relation(&p, LVM_LE);
897 lvm_set_variable(&p,
"a");
898 lvm_set_long(&p, 100);
899 lvm_set_relation(&p, LVM_GE);
900 lvm_set_long(&p, 10);
901 lvm_set_variable(&p,
"a");
904 lvm_print_derivations(&p);
907 lvm_reset(&p, code,
sizeof(code));
908 lvm_register_variable(
"a", LVM_LONG);
909 lvm_register_variable(
"b", LVM_LONG);
910 lvm_set_relation(&p, LVM_AND);
911 lvm_set_relation(&p, LVM_LE);
912 lvm_set_variable(&p,
"a");
913 lvm_set_long(&p, 100);
914 lvm_set_relation(&p, LVM_GE);
915 lvm_set_variable(&p,
"b");
916 lvm_set_long(&p, 100);
919 lvm_print_derivations(&p);
922 lvm_reset(&p, code,
sizeof(code));
923 lvm_register_variable(
"a", LVM_LONG);
924 lvm_set_relation(&p, LVM_OR);
925 lvm_set_relation(&p, LVM_LE);
926 lvm_set_variable(&p,
"a");
927 lvm_set_long(&p, 100);
928 lvm_set_relation(&p, LVM_OR);
929 lvm_set_relation(&p, LVM_LE);
930 lvm_set_long(&p, 1000);
931 lvm_set_variable(&p,
"a");
932 lvm_set_relation(&p, LVM_LE);
933 lvm_set_variable(&p,
"a");
934 lvm_set_long(&p, 1902);
937 lvm_print_derivations(&p);
941 lvm_reset(&p, code,
sizeof(code));
942 lvm_register_variable(
"a", LVM_LONG);
943 lvm_register_variable(
"b", LVM_LONG);
945 lvm_set_relation(&p, LVM_OR);
946 lvm_set_relation(&p, LVM_GE);
947 lvm_set_variable(&p,
"b");
948 lvm_set_long(&p, 10000);
950 lvm_set_relation(&p, LVM_AND);
951 lvm_set_relation(&p, LVM_LE);
952 lvm_set_variable(&p,
"a");
953 lvm_set_long(&p, 100);
954 lvm_set_relation(&p, LVM_AND);
955 lvm_set_relation(&p, LVM_LE);
956 lvm_set_variable(&p,
"a");
957 lvm_set_long(&p, 90);
958 lvm_set_relation(&p, LVM_AND);
959 lvm_set_relation(&p, LVM_GE);
960 lvm_set_variable(&p,
"a");
961 lvm_set_long(&p, 80);
962 lvm_set_relation(&p, LVM_LE);
963 lvm_set_variable(&p,
"a");
964 lvm_set_long(&p, 105);
967 lvm_print_derivations(&p);
Definitions and declarations for AQL, the Antelope Query Language.
#define NULL
The null pointer.
int main(void)
This is main...
Definitions and declarations for the Propositional Logic Engine.
#define TRUE
An alias for one, used for clarity.
A set of debugging macros.