fix generation of graph files
[repair.git] / Repair / RepairCompiler / MCC / IR / RelationExpr.java
index b966628be324d52be7701c935b1172ed867a7d02..4026b31c0368ad56ae2c5430d8ecac83be206dfe 100755 (executable)
@@ -8,34 +8,114 @@ public class RelationExpr extends Expr {
     RelationDescriptor relation;
     boolean inverse;
 
+    public Set getfunctions() {
+       HashSet functions=new HashSet();
+       Set exprfunctions=expr.getfunctions();
+       if (exprfunctions!=null)
+           functions.addAll(exprfunctions);
+       functions.add(new ConstraintDependence.Function(relation,expr.getSet(),inverse,this));
+
+       return functions;
+    }
+
+    public SetDescriptor getSet() {
+       if (inverse)
+           return relation.getDomain();
+       else
+           return relation.getRange();
+    }
+
     public RelationExpr(Expr expr, RelationDescriptor relation, boolean inverse) {
         this.expr = expr;
         this.relation = relation;
         this.inverse = inverse;
     }
 
+    public Set freeVars() {
+       return expr.freeVars();
+    }
+
+    public String name() {
+       String name=expr.name()+".";
+       if (inverse)
+           name+="~";
+       name+=relation.toString();
+       return name;
+    }
+
+    public Expr getExpr() {
+        return expr;
+    }
+
+    public boolean equals(Map remap, Expr e) {
+       if (e==null||!(e instanceof RelationExpr))
+           return false;
+       RelationExpr re=(RelationExpr)e;
+       if (re.relation!=relation)
+           return false;
+       if (!expr.equals(remap,re.expr))
+           return false;
+       if (inverse!=re.inverse)
+           return false;
+       return true;
+    }
+
+    public boolean usesDescriptor(Descriptor rd) {
+       if (rd==relation)
+           return true;
+       else
+           return expr.usesDescriptor(rd);
+    }
+
+    public Set useDescriptor(Descriptor rd) {
+       HashSet newset=new HashSet();
+       if (rd==relation)
+           newset.add(this);
+       newset.addAll(expr.useDescriptor(rd));
+       return newset;
+    }
+
+    public RelationDescriptor getRelation() {
+        return relation;
+    }
+
+    public Descriptor getDescriptor() {
+        return relation;
+    }
+
+    public boolean inverted() {
+        return inverse;
+    }
+
+    public Set getInversedRelations() {
+        Set set = expr.getInversedRelations();
+        if (inverse) {
+            set.add(relation);
+        }
+        return set;
+    }
+
     public Set getRequiredDescriptors() {
-        Set v = expr.getRequiredDescriptors();        
+        Set v = expr.getRequiredDescriptors();
         v.add(relation);
         return v;
     }
 
     public void generate(CodeWriter writer, VarDescriptor dest) {
         VarDescriptor domain = VarDescriptor.makeNew("domain");
+        String strinverse = inverse ? "inv" : "";
+        String found = (VarDescriptor.makeNew("found")).getSafeSymbol();
         expr.generate(writer, domain);
-        writer.outputline(relation.getRange().getType().getSafeSymbol() + " " + dest.getSymbol() + " = " + relation.getSafeSymbol() + "_hash->get(" + domain.getSafeSymbol() + ");");
-    }
-
-    public void generate_set(CodeWriter writer, VarDescriptor dest) {
-        VarDescriptor domain = VarDescriptor.makeNew("domain");
-        expr.generate(writer, domain);
-        writer.outputline(relation.getRange().getType().getSafeSymbol() + " " + dest.getSymbol() + " = " + relation.getSafeSymbol() + "_hash->get(" + domain.getSafeSymbol() + ");");
+        writer.addDeclaration(relation.getRange().getType().getGenerateType().getSafeSymbol(), dest.getSafeSymbol());
+       writer.addDeclaration("int",found);
+       writer.outputline(found+" = SimpleHashget(" +relation.getSafeSymbol()+"_hash"+strinverse+", "+ domain.getSafeSymbol() + ", & " + dest.getSafeSymbol() + ");");
+       writer.outputline("if (!" + found + ") { maybe = 1; }");
     }
 
     public void prettyPrint(PrettyPrinter pp) {
         expr.prettyPrint(pp);
         pp.output(".");
-        
+
         if (inverse) {
             pp.output("~");
         }
@@ -46,7 +126,7 @@ public class RelationExpr extends Expr {
     public TypeDescriptor typecheck(SemanticAnalyzer sa) {
 
         TypeDescriptor type = expr.typecheck(sa);
-        
+
         if (type == null) {
             return null;
         }
@@ -54,23 +134,23 @@ public class RelationExpr extends Expr {
         /* check to make sure that the types of the relation match up */
         if (inverse) {
             TypeDescriptor rangetype = relation.getRange().getType();
-            
+
             if (rangetype != type) {
-                sa.getErrorReporter().report(null, "Type of left side of relation operator '.' is '" + type.getSymbol() + 
-                                    "' but must be the '" + rangetype.getSymbol() + 
+                sa.getErrorReporter().report(null, "Type of left side of relation operator '.' is '" + type.getSymbol() +
+                                    "' but must be '" + rangetype.getSymbol() +
                                     "', the type of the range of the relation '" + relation.getSymbol() + "'");
                 return null;
             }
-            
+
             this.td = relation.getDomain().getType();
             return this.td;
         } else { /* not inverse */
             TypeDescriptor domaintype = relation.getDomain().getType();
-            
+
             if (domaintype != type) {
-                sa.getErrorReporter().report(null, "Type of left side of relation operator '.' is '" + type.getSymbol() + 
-                                    "' but must be the '" + domaintype.getSymbol() + 
-                                    "', the type of the range of the relation '" + relation.getSymbol() + "'");
+                sa.getErrorReporter().report(null, "Type of left side of relation operator '.' is '" + type.getSymbol() +
+                                    "' but must be '" + domaintype.getSymbol() +
+                                    "', the type of the domain of the relation '" + relation.getSymbol() + "'");
                 return null;
             }