46#define DEBUG DEBUG_NONE
56#ifndef LVM_MAX_NAME_LENGTH
57#define LVM_MAX_NAME_LENGTH 16
60#ifndef LVM_MAX_VARIABLE_ID
61#define LVM_MAX_VARIABLE_ID 8
65#define LVM_USE_FLOATS 0
68#define IS_CONNECTIVE(op) ((op) & LVM_CONNECTIVE)
72 operand_value_t value;
73 char name[LVM_MAX_NAME_LENGTH + 1];
75typedef struct variable variable_t;
82typedef struct derivation derivation_t;
86static variable_t variables[LVM_MAX_VARIABLE_ID];
89static derivation_t derivations[LVM_MAX_VARIABLE_ID];
93print_derivations(derivation_t *d)
97 for(i = 0; i < LVM_MAX_VARIABLE_ID; i++) {
99 printf(
"%s is constrained to (%ld,%ld)\n", variables[i].name,
100 d[i].min.l, d[i].max.l);
111 for(var = variables; var <= &variables[LVM_MAX_VARIABLE_ID - 1] && var->name[0] !=
'\0'; var++) {
112 if(strcmp(var->name, name) == 0) {
117 return (variable_id_t)(var - &variables[0]);
121get_operator(lvm_instance_t *p)
123 operator_t *
operator;
125 operator = (operator_t *)&p->code[p->ip];
126 p->ip +=
sizeof(operator_t);
131get_operand(lvm_instance_t *p, operand_t *operand)
133 memcpy(operand, &p->code[p->ip],
sizeof(*operand));
134 p->ip +=
sizeof(*operand);
138get_type(lvm_instance_t *p)
140 node_type_t node_type;
142 node_type = *(node_type_t *)(p->code + p->ip);
143 p->ip +=
sizeof(node_type);
149operand_to_long(operand_t *operand)
151 switch(operand->type) {
153 return operand->value.l;
156 return (
long)operand->value.f;
160 return variables[operand->value.id].value.l;
167eval_expr(lvm_instance_t *p, operator_t op, operand_t *result)
171 operator_t *
operator;
172 operand_t operand[2];
177 for(i = 0; i < 2; i++) {
181 operator = get_operator(p);
182 r = eval_expr(p, *
operator, &operand[i]);
188 get_operand(p, &operand[i]);
191 return LVM_SEMANTIC_ERROR;
193 value[i] = operand_to_long(&operand[i]);
208 return LVM_MATH_ERROR;
213 return LVM_EXECUTION_ERROR;
216 result->type = LVM_LONG;
217 result->value.l = result_value;
223eval_logic(lvm_instance_t *p, operator_t *op)
230 operator_t *
operator;
235 if(IS_CONNECTIVE(*op)) {
236 arguments = *op == LVM_NOT ? 1 : 2;
237 for(i = 0; i < arguments; i++) {
239 if(type != LVM_CMP_OP) {
240 return LVM_SEMANTIC_ERROR;
242 operator = get_operator(p);
243 logic_result[i] = eval_logic(p,
operator);
244 if(LVM_ERROR(logic_result[i])) {
245 return logic_result[i];
250 return !logic_result[0];
251 }
else if(*op == LVM_AND) {
252 return logic_result[0] == LVM_TRUE && logic_result[1] == LVM_TRUE;
254 return logic_result[0] == LVM_TRUE || logic_result[1] == LVM_TRUE;
258 for(i = 0; i < 2; i++) {
262 operator = get_operator(p);
263 r = eval_expr(p, *
operator, &operand);
269 get_operand(p, &operand);
272 return LVM_SEMANTIC_ERROR;
274 result[i] = operand_to_long(&operand);
279 PRINTF(
"Result1: %ld\nResult2: %ld\n", l1, l2);
298 return LVM_EXECUTION_ERROR;
302lvm_reset(lvm_instance_t *p,
unsigned char *code, lvm_ip_t size)
304 memset(code, 0, size);
311 memset(variables, 0,
sizeof(variables));
312 memset(derivations, 0,
sizeof(derivations));
316lvm_jump_to_operand(lvm_instance_t *p)
321 p->end +=
sizeof(operator_t) +
sizeof(node_type_t);
322 if(p->end >= p->size) {
331lvm_shift_for_operator(lvm_instance_t *p, lvm_ip_t end)
338 if(p->end +
sizeof(operator_t) +
sizeof(node_type_t) > p->size ||
346 memmove(ptr +
sizeof(operator_t) +
sizeof(node_type_t), ptr, old_end - end);
349 return old_end +
sizeof(operator_t) +
sizeof(node_type_t);
353lvm_get_end(lvm_instance_t *p)
359lvm_set_end(lvm_instance_t *p, lvm_ip_t end)
375lvm_execute(lvm_instance_t *p)
378 operator_t *
operator;
382 status = LVM_EXECUTION_ERROR;
386 operator = get_operator(p);
387 status = eval_logic(p,
operator);
388 if(!LVM_ERROR(status)) {
389 PRINTF(
"The statement is %s\n", status == LVM_TRUE ?
"true" :
"false");
391 PRINTF(
"Execution error: %d\n", (
int)status);
395 PRINTF(
"Error: The code must start with a relational operator\n");
402lvm_set_type(lvm_instance_t *p, node_type_t type)
404 if(p->end +
sizeof(node_type_t) >= DB_VM_BYTECODE_SIZE) {
405 PRINTF(
"Error: overflow in lvm_set_type\n");
406 return LVM_STACK_OVERFLOW;
409 *(node_type_t *)(p->code + p->end) = type;
410 p->end +=
sizeof(type);
415lvm_set_op(lvm_instance_t *p, operator_t op)
419 status = lvm_set_type(p, LVM_ARITH_OP);
420 if(status != LVM_TRUE) {
424 if(p->end +
sizeof(op) >= DB_VM_BYTECODE_SIZE) {
425 PRINTF(
"Error: overflow in lvm_set_op\n");
426 return LVM_STACK_OVERFLOW;
429 memcpy(&p->code[p->end], &op,
sizeof(op));
430 p->end +=
sizeof(op);
435lvm_set_relation(lvm_instance_t *p, operator_t op)
439 status = lvm_set_type(p, LVM_CMP_OP);
440 if(status != LVM_TRUE) {
444 if(p->end +
sizeof(op) >= DB_VM_BYTECODE_SIZE) {
445 PRINTF(
"Error: overflow in lvm_set_relation\n");
446 return LVM_STACK_OVERFLOW;
449 memcpy(&p->code[p->end], &op,
sizeof(op));
450 p->end +=
sizeof(op);
455lvm_set_operand(lvm_instance_t *p, operand_t *op)
459 status = lvm_set_type(p, LVM_OPERAND);
460 if(status != LVM_TRUE) {
464 if(p->end +
sizeof(*op) >= DB_VM_BYTECODE_SIZE) {
465 PRINTF(
"Error: overflow in lvm_set_operand\n");
466 return LVM_STACK_OVERFLOW;
469 memcpy(&p->code[p->end], op,
sizeof(*op));
470 p->end +=
sizeof(*op);
475lvm_set_long(lvm_instance_t *p,
long l)
482 return lvm_set_operand(p, &op);
486lvm_register_variable(
char *name, operand_type_t type)
492 if(
id == LVM_MAX_VARIABLE_ID) {
493 return LVM_VARIABLE_LIMIT_REACHED;
496 var = &variables[id];
497 if(var->name[0] ==
'\0') {
498 strncpy(var->name, name,
sizeof(var->name) - 1);
499 var->name[
sizeof(var->name) - 1] =
'\0';
507lvm_set_variable_value(
char *name, operand_value_t
value)
512 if(
id == LVM_MAX_VARIABLE_ID) {
513 return LVM_INVALID_IDENTIFIER;
516 variables[id].value =
value;
521lvm_set_variable(lvm_instance_t *p,
char *name)
527 if(
id == LVM_MAX_VARIABLE_ID) {
528 return LVM_INVALID_IDENTIFIER;
531 PRINTF(
"var id = %d\n",
id);
532 op.type = LVM_VARIABLE;
534 return lvm_set_operand(p, &op);
538lvm_clone(lvm_instance_t *dst, lvm_instance_t *src)
540 memcpy(dst, src,
sizeof(*dst));
544create_intersection(derivation_t *result, derivation_t *d1, derivation_t *d2)
548 for(i = 0; i < LVM_MAX_VARIABLE_ID; i++) {
549 if(!d1[i].derived && !d2[i].derived) {
551 }
else if(d1[i].derived && !d2[i].derived) {
552 result[i].min.l = d1[i].min.l;
553 result[i].max.l = d1[i].max.l;
554 }
else if(!d1[i].derived && d2[i].derived) {
555 result[i].min.l = d2[i].min.l;
556 result[i].max.l = d2[i].max.l;
560 if(d1[i].min.l > d2[i].min.l) {
561 result[i].min.l = d1[i].min.l;
563 result[i].min.l = d2[i].min.l;
566 if(d1[i].max.l < d2[i].max.l) {
567 result[i].max.l = d1[i].max.l;
569 result[i].max.l = d2[i].max.l;
572 result[i].derived = 1;
576 PRINTF(
"Created an intersection of D1 and D2\n");
578 print_derivations(d1);
580 print_derivations(d2);
581 PRINTF(
"Result: \n");
582 print_derivations(result);
587create_union(derivation_t *result, derivation_t *d1, derivation_t *d2)
591 for(i = 0; i < LVM_MAX_VARIABLE_ID; i++) {
592 if(!d1[i].derived && !d2[i].derived) {
594 }
else if(d1[i].derived && !d2[i].derived) {
595 result[i].min.l = d1[i].min.l;
596 result[i].max.l = d1[i].max.l;
597 }
else if(!d1[i].derived && d2[i].derived) {
598 result[i].min.l = d2[i].min.l;
599 result[i].max.l = d2[i].max.l;
603 if(d1[i].min.l > d2[i].min.l) {
604 result[i].min.l = d2[i].min.l;
606 result[i].min.l = d1[i].min.l;
609 if(d1[i].max.l < d2[i].max.l) {
610 result[i].max.l = d2[i].max.l;
612 result[i].max.l = d1[i].max.l;
615 result[i].derived = 1;
619 PRINTF(
"Created a union of D1 and D2\n");
621 print_derivations(d1);
623 print_derivations(d2);
624 PRINTF(
"Result: \n");
625 print_derivations(result);
630derive_relation(lvm_instance_t *p, derivation_t *local_derivations)
632 operator_t *
operator;
634 operand_t operand[2];
637 operand_value_t *
value;
638 derivation_t *derivation;
641 operator = get_operator(p);
643 if(IS_CONNECTIVE(*
operator)) {
644 derivation_t d1[LVM_MAX_VARIABLE_ID];
645 derivation_t d2[LVM_MAX_VARIABLE_ID];
647 if(*
operator != LVM_AND && *
operator != LVM_OR) {
648 return LVM_DERIVATION_ERROR;
651 PRINTF(
"Attempting to infer ranges from a logical connective\n");
653 memset(d1, 0,
sizeof(d1));
654 memset(d2, 0,
sizeof(d2));
656 if(LVM_ERROR(derive_relation(p, d1)) ||
657 LVM_ERROR(derive_relation(p, d2))) {
658 return LVM_DERIVATION_ERROR;
661 if(*
operator == LVM_AND) {
662 create_intersection(local_derivations, d1, d2);
663 }
else if(*
operator == LVM_OR) {
664 create_union(local_derivations, d1, d2);
669 for(i = 0; i < 2; i++) {
673 get_operand(p, &operand[i]);
676 return LVM_DERIVATION_ERROR;
680 if(operand[0].type == LVM_VARIABLE && operand[1].type == LVM_VARIABLE) {
681 return LVM_DERIVATION_ERROR;
685 if(operand[0].type == LVM_VARIABLE) {
686 if(operand[1].type == LVM_VARIABLE) {
687 return LVM_DERIVATION_ERROR;
689 variable_id = operand[0].value.id;
690 value = &operand[1].value;
692 variable_id = operand[1].value.id;
693 value = &operand[0].value;
696 if(variable_id >= LVM_MAX_VARIABLE_ID) {
697 return LVM_DERIVATION_ERROR;
700 PRINTF(
"variable id %d, value %ld\n", variable_id, *(
long *)
value);
702 derivation = local_derivations + variable_id;
704 derivation->max.l = LONG_MAX;
705 derivation->min.l = LONG_MIN;
709 derivation->max = *
value;
710 derivation->min = *
value;
713 derivation->min.l =
value->l + 1;
716 derivation->min.l =
value->l;
719 derivation->max.l =
value->l - 1;
722 derivation->max.l =
value->l;
725 return LVM_DERIVATION_ERROR;
728 derivation->derived = 1;
734lvm_derive(lvm_instance_t *p)
736 return derive_relation(p, derivations);
740lvm_get_derived_range(lvm_instance_t *p,
char *name,
741 operand_value_t *min, operand_value_t *max)
745 for(i = 0; i < LVM_MAX_VARIABLE_ID; i++) {
746 if(strcmp(name, variables[i].name) == 0) {
747 if(derivations[i].derived) {
748 *min = derivations[i].min;
749 *max = derivations[i].max;
752 return LVM_DERIVATION_ERROR;
755 return LVM_INVALID_IDENTIFIER;
760print_operator(lvm_instance_t *p, lvm_ip_t index)
763 struct operator_map {
765 char *representation;
767 struct operator_map operator_map[] = {
784 memcpy(&
operator, p->code + index,
sizeof(
operator));
787 if(operator_map[i].op ==
operator) {
788 PRINTF(
"%s ", operator_map[i].representation);
793 return index +
sizeof(operator_t);
797print_operand(lvm_instance_t *p, lvm_ip_t index)
801 memcpy(&operand, p->code + index,
sizeof(operand));
803 switch(operand.type) {
805 if(operand.value.id >= LVM_MAX_VARIABLE_ID ||
806 variables[operand.value.id].name == NULL) {
807 PRINTF(
"var(id:%d):?? ", operand.value.id);
809 PRINTF(
"var(%s):%ld ", variables[operand.value.id].name,
810 variables[operand.value.id].value.l);
814 PRINTF(
"long:%ld ", operand.value.l);
821 return index +
sizeof(operand_t);
825print_relation(lvm_instance_t *p, lvm_ip_t index)
828 return print_operator(p, index);
833lvm_print_code(lvm_instance_t *p)
840 for(ip = 0; ip < p->end;) {
841 switch(*(node_type_t *)(p->code + ip)) {
843 ip = print_relation(p, ip +
sizeof(node_type_t));
846 ip = print_operator(p, ip +
sizeof(node_type_t));
849 ip = print_operand(p, ip +
sizeof(node_type_t));
852 PRINTF(
"Invalid opcode: 0x%x ", p->code[ip]);
862lvm_print_derivations(lvm_instance_t *p)
865 print_derivations(derivations);
874 unsigned char code[256];
876 lvm_reset(&p, code,
sizeof(code));
878 lvm_register_variable(
"z", LVM_LONG);
879 lvm_set_variable_value(
"z", (operand_value_t)15L);
881 lvm_register_variable(
"y", LVM_LONG);
882 lvm_set_variable_value(
"y", (operand_value_t)109L);
885 lvm_set_relation(&p, LVM_AND);
886 lvm_set_relation(&p, LVM_EQ);
887 lvm_set_long(&p, 109);
888 lvm_set_variable(&p,
"y");
889 lvm_set_relation(&p, LVM_GE);
890 lvm_set_long(&p, 20);
891 lvm_set_op(&p, LVM_SUB);
892 lvm_set_long(&p, 70);
893 lvm_set_op(&p, LVM_ADD);
895 lvm_set_op(&p, LVM_MUL);
896 lvm_set_variable(&p,
"z");
904 lvm_reset(&p, code,
sizeof(code));
905 lvm_set_relation(&p, LVM_NOT);
906 lvm_set_relation(&p, LVM_LE);
907 lvm_set_op(&p, LVM_ADD);
908 lvm_set_long(&p, 9999);
910 lvm_set_op(&p, LVM_ADD);
911 lvm_set_long(&p, -1);
912 lvm_set_long(&p, 10001);
921 lvm_reset(&p, code,
sizeof(code));
922 lvm_register_variable(
"a", LVM_LONG);
923 lvm_set_relation(&p, LVM_EQ);
924 lvm_set_variable(&p,
"a");
928 lvm_print_derivations(&p);
931 lvm_reset(&p, code,
sizeof(code));
932 lvm_register_variable(
"a", LVM_LONG);
933 lvm_set_relation(&p, LVM_LE);
934 lvm_set_variable(&p,
"a");
935 lvm_set_long(&p, 10);
938 lvm_print_derivations(&p);
941 lvm_reset(&p, code,
sizeof(code));
942 lvm_register_variable(
"a", LVM_LONG);
943 lvm_set_relation(&p, LVM_AND);
944 lvm_set_relation(&p, LVM_LE);
945 lvm_set_variable(&p,
"a");
946 lvm_set_long(&p, 100);
947 lvm_set_relation(&p, LVM_GE);
948 lvm_set_long(&p, 10);
949 lvm_set_variable(&p,
"a");
952 lvm_print_derivations(&p);
955 lvm_reset(&p, code,
sizeof(code));
956 lvm_register_variable(
"a", LVM_LONG);
957 lvm_register_variable(
"b", LVM_LONG);
958 lvm_set_relation(&p, LVM_AND);
959 lvm_set_relation(&p, LVM_LE);
960 lvm_set_variable(&p,
"a");
961 lvm_set_long(&p, 100);
962 lvm_set_relation(&p, LVM_GE);
963 lvm_set_variable(&p,
"b");
964 lvm_set_long(&p, 100);
967 lvm_print_derivations(&p);
970 lvm_reset(&p, code,
sizeof(code));
971 lvm_register_variable(
"a", LVM_LONG);
972 lvm_set_relation(&p, LVM_OR);
973 lvm_set_relation(&p, LVM_LE);
974 lvm_set_variable(&p,
"a");
975 lvm_set_long(&p, 100);
976 lvm_set_relation(&p, LVM_OR);
977 lvm_set_relation(&p, LVM_LE);
978 lvm_set_long(&p, 1000);
979 lvm_set_variable(&p,
"a");
980 lvm_set_relation(&p, LVM_LE);
981 lvm_set_variable(&p,
"a");
982 lvm_set_long(&p, 1902);
985 lvm_print_derivations(&p);
989 lvm_reset(&p, code,
sizeof(code));
990 lvm_register_variable(
"a", LVM_LONG);
991 lvm_register_variable(
"b", LVM_LONG);
993 lvm_set_relation(&p, LVM_OR);
994 lvm_set_relation(&p, LVM_GE);
995 lvm_set_variable(&p,
"b");
996 lvm_set_long(&p, 10000);
998 lvm_set_relation(&p, LVM_AND);
999 lvm_set_relation(&p, LVM_LE);
1000 lvm_set_variable(&p,
"a");
1001 lvm_set_long(&p, 100);
1002 lvm_set_relation(&p, LVM_AND);
1003 lvm_set_relation(&p, LVM_LE);
1004 lvm_set_variable(&p,
"a");
1005 lvm_set_long(&p, 90);
1006 lvm_set_relation(&p, LVM_AND);
1007 lvm_set_relation(&p, LVM_GE);
1008 lvm_set_variable(&p,
"a");
1009 lvm_set_long(&p, 80);
1010 lvm_set_relation(&p, LVM_LE);
1011 lvm_set_variable(&p,
"a");
1012 lvm_set_long(&p, 105);
1015 lvm_print_derivations(&p);
Definitions and declarations for AQL, the Antelope Query Language.
Default definitions of C compiler quirk work-arounds.
#define CC_ARRAY_LENGTH(array)
Counts the number of elements of an array.
A set of debugging macros.
static int value(int type)
Definitions and declarations for the Propositional Logic Engine.