Files
secondo/Algebras/TopRel/Tree.c
2026-01-23 17:03:45 +08:00

210 lines
5.5 KiB
C

/*
----
This file is part of SECONDO.
Copyright (C) 2004, University in Hagen, Department of Computer Science,
Database Systems for New Applications.
SECONDO is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
SECONDO is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with SECONDO; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
----
1 The Tree implementation
In this file are the functions for creating and manipulation
operator trees
*/
#include "Tree.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
enum OPERATORS { OPAND, OPXOR, OPOR, OPNOT, OPCONDITIONAL,
OPBICONDITIONAL};
struct tree* createConstant(int value){
struct tree* t = (struct tree*) malloc(sizeof(struct tree));
t->defined = 1;
t->type = CONSTANT;
if(!value)
t->value=0;
else
t->value=1;
t->son1=0;
t->son2=0;
return t;
}
struct tree* createVariable(int value){
struct tree* t = (struct tree*) malloc(sizeof(struct tree));
t->defined = 1;
t->type = VARIABLE;
t->value=value;
t->son1=0;
t->son2=0;
return t;
}
struct tree* createNonLeaf(int type, int value,
struct tree* son1,struct tree* son2){
struct tree* t = (struct tree*) malloc(sizeof(struct tree));
t->type = type;
t->value=value;
t->son1=son1;
t->son2=son2;
t->defined = 1;
if(son1 && !son1->defined)
t->defined=0;
if(son2 && !son2->defined)
t->defined=0;
return t;
}
struct tree* createAnd(struct tree* s1, struct tree* s2){
return createNonLeaf(OP2,OPAND,s1,s2);
}
struct tree* createOr(struct tree* s1, struct tree* s2){
return createNonLeaf(OP2,OPOR,s1,s2);
}
struct tree* createXor(struct tree* s1, struct tree* s2){
return createNonLeaf(OP2,OPXOR,s1,s2);
}
struct tree* createConditional(struct tree* s1, struct tree* s2){
return createNonLeaf(OP2,OPCONDITIONAL,s1,s2);
}
struct tree* createBiconditional(struct tree* s1, struct tree* s2){
return createNonLeaf(OP2,OPBICONDITIONAL,s1,s2);
}
struct tree* createNot(struct tree* s1){
return createNonLeaf(OP1,OPNOT,s1,0);
}
void destroyTree(struct tree* victim){
if(victim->son1)
destroyTree(victim->son1);
if(victim->son2)
destroyTree(victim->son2);
free(victim);
victim = 0;
}
int evalTree(struct tree* t, unsigned short number){
if(!t){
printf("try to evaluate an empty tree");
return 0;
}
if(!t->defined){
printf("error: undefined tree detected");
return 0;
}
int s1,s2;
if(t->type == CONSTANT)
return t->value != 0;
if(t->type == VARIABLE){
return ((t->value) & number)!=0;
}
// operator
switch (t->value){
case OPNOT: s1 = evalTree(t->son1,number);
return !s1;
case OPAND: s1 = evalTree(t->son1,number);
s2 = evalTree(t->son2,number);
return s1 && s2;
case OPOR: s1 = evalTree(t->son1,number);
s2 = evalTree(t->son2,number);
return s1 || s2;
case OPXOR: s1 = evalTree(t->son1,number);
s2 = evalTree(t->son2,number);
return s1 ^ s2;
case OPCONDITIONAL: s1 = evalTree(t->son1,number);
s2 = evalTree(t->son2,number);
return !s1 || s2;
case OPBICONDITIONAL: s1 = evalTree(t->son1,number);
s2 = evalTree(t->son2,number);
return s1==s2;
}
printf("unknown operator");
return -1;
}
void printTree(struct tree* t){
if(t){
if(t->type==CONSTANT){
if(t->value)
printf("true");
else
printf("false");
return;
}
if(t->type==VARIABLE){
switch(t->value){
case ii : printf("ii");break;
case ib : printf("ib");break;
case ie : printf("ie");break;
case bi : printf("bi");break;
case bb : printf("bb");break;
case be : printf("be");break;
case ei : printf("ei");break;
case eb : printf("eb");break;
case ee : printf("ee");break;
default : printf(" error-unknown variable %d",t->value);
}
return;
}
if(t->type==OP1){
if(t->value==OPNOT){
printf("not ");
if(!t->son1){
printf("error in argument of 'not'\n" );
}else{
printf("(");
printTree(t->son1);
printf(")");
}
}else{
printf(" unknown unary operator ");
}
return;
}
if(t->type==OP2){
printf("("); printTree(t->son1); printf(")");
switch(t->value){
case OPAND : printf(" and ");break;
case OPOR : printf(" or ");break;
case OPXOR : printf(" xor ");break;
default: printf("unknown binary operator");
}
printf("(");
printTree(t->son2);
printf(")");
return;
}
printf("unknown type for tree");
} else{
printf("empty tree");
}
}