예제 #1
0
    public void CompileDatatype1Ghost(Type t, TypeApply app, TextWriter writer, TextWriter iwriter)
    {
        // type List = Nil() | Cons(hd:int, tl:List);
        string dataName           = app.AppName(); // List
        List <DatatypeCtor> ctors = compileDatatypes[app].AsDatatype.Ctors;
        bool isSeq = dataName.StartsWith("Seq_");

        if (isSeq)
        {
            iwriter.WriteLine("type " + dataName + ";");
        }
        (isSeq ? writer : iwriter).WriteLine(
            "type " + (isSeq ? "implementation" : "") + "{:overload} " + dataName + " = "
            + String.Join(" | ", ctors.Select(c => Compile_Constructor(t, c.Name, app.typeArgs).AppName() + "("
                                              + String.Join(", ", c.Formals.Select(f => f.Name + ":" + TypeString(app.AppType(f.Type))))
                                              + ")")) + ";");

        if (isSeq)
        {
            foreach (var c in ctors)
            {
                string cName = Compile_Constructor(t, c.Name, app.typeArgs).AppName();
                string args  = String.Join(", ", c.Formals.Select(f => f.Name));
                string parms = String.Join(", ", c.Formals.Select(f => f.Name + ":"
                                                                  + TypeString(app.AppType(f.Type))));
                iwriter.WriteLine("function _" + cName + "(" + parms + "):" + dataName + ";");
                writer.WriteLine("function implementation _" + cName + "(" + parms + "):"
                                 + dataName + " { " + cName + "(" + args + ") }");
                foreach (var f in c.Formals)
                {
                    string tName = TypeString(app.AppType(f.Type));
                    iwriter.WriteLine("function " + f.Name + "_" + cName + "(x:" + dataName
                                      + "):" + tName + ";");
                    writer.WriteLine("function implementation " + f.Name + "_" + cName + "(x:" + dataName
                                     + "):" + tName + " { " + f.Name + "#" + cName + "(x) }");
                }
                iwriter.WriteLine("function is_" + cName + "(x:" + dataName + "):bool;");
                writer.WriteLine("function implementation is_" + cName + "(x:" + dataName
                                 + "):bool { x is " + cName + " }");
            }
        }
    }
예제 #2
0
    void CompileDatatype2(Type t, TypeApply app)
    {
        string dataName = app.AppName(); 
        string suffix = dataName.Substring(((UserDefinedType)t).Name.Length);
        bool isSeq = dataName.StartsWith("Seq_");
        string lemma = isSeq ? "call proc_Seq__Cons__All" + suffix + "();" : "";
        TextWriter iwriter = heapIWriter;
        List<DatatypeCtor> ctors = compileDatatypes[app].AsDatatype.Ctors;

        
        Func<string,string> dataIs = c => isSeq ? ("is_" + c + "(data)") : ("data is " + c);
        string tags = String.Join(" || ", ctors.Select(c =>
            "(r.regs[x] == Tag_" + dataName + "_" + c.Name + " && " + dataIs(
            Compile_Constructor(t, c.Name, app.typeArgs).AppName()) + ")"));
        iwriter.WriteLine(loadTagDecl(dataName, tags));
        heapWriter.WriteLine("implementation loadTag_" + dataName
            + "(my r_old:regs, const my core_state:core_state, const linear stk:mem, const linear statics:mem, const linear io:IOState, linear mems_old:mems, $commonVars:commonVars, $gcVars:gcVars, $toAbs:[int]int, $absMem:[int][int]int, $stacksFrames:[int]Frames, objLayouts:[int]ObjLayout, heap:Heap, x:int, y:opn_mem, data:"
            + dataName + ", abs:int, obj:int)");
        heapWriter.WriteLine("  returns(my r:regs, linear mems:mems)");
        heapWriter.WriteLine("{");
        heapWriter.WriteLine("  assert THeapValue(objLayouts, true, $toAbs, obj, abs);");
        heapWriter.WriteLine("  assert THeapInv($absMem, objLayouts, heap);");
        heapWriter.WriteLine("  " + lemma);
        heapWriter.WriteLine("  call r, mems := gcLoadField(r_old, core_state, stk, statics, io, mems_old,");
        heapWriter.WriteLine("    $commonVars, $gcVars, $absMem, $toAbs, $stacksFrames, objLayouts,");
        heapWriter.WriteLine("    x, y, obj - 4, 2);");
        heapWriter.WriteLine("}");

        foreach (var ctor in ctors)
        {
            var ints = ctor.Formals.Where(x => !IsPtrType(app.AppType(x.Type))).ToList();
            var ptrs = ctor.Formals.Where(x =>  IsPtrType(app.AppType(x.Type))).ToList();
            var sorted = ints.Concat(ptrs).ToList();
            string ctorName = Compile_Constructor(t, ctor.Name, app.typeArgs).AppName();
            string cons = isSeq ? ("_" + ctorName) : ctorName;

            
            string parms = String.Join(", ", ctor.Formals.Select(
                c => "arg_" + c.Name + ":" + TypeString(app.AppType(c.Type))));
            
            string args = String.Join(", ", ctor.Formals.Select(c => "arg_" + c.Name));
            int argRetSize = 4 + 4 * Math.Max(ints.Count, ptrs.Count);
            heapIWriter.WriteLine("const stack_size__DafnyCC__Proc_Alloc_" + ctorName + ":int := 256;");
            iwriter.WriteLine(allocDecl1(
                                         dataName,
                                         ctorName,
                                         cons,
                                         parms,
                                         args,
                                         argRetSize.ToString()));
            string triggers = (IPSize == 8) ? String.Format("{0} && {1}", GcTO64(1), GcTO(3)) : GcTO(1);
            for (int i = 0; i < ints.Count; i++)
            {
                
                string val = "stk_old.map[r_old.regs[ESP] + "
                    + (IPSize + 4 * i) + "]";
                iwriter.WriteLine("requires " + CompileBase.IntEqTyped(app.AppType(ints[i].Type), "arg_" + ints[i].Name, val) + ";");
                triggers += String.Format(" && {0}", (IPSize == 8 ? StackTO64(i + 1): StackTO(i + 1)));
            }
            for (int i = 0; i < ptrs.Count; i++)
            {
                
                iwriter.WriteLine("requires StackAbsSlot(heap_old, $stacksFrames_old, r_old.regs[ESP] + "
                    + (IPSize + 4 + 4 * i) + " + stackGcOffset) == Abs_" + TypeString(app.AppType(ptrs[i].Type))
                    + "(arg_" + ptrs[i].Name + ");");
                triggers += String.Format(" && {0}", (IPSize == 8 ? GcTO64(i + 2): GcTO(i + 2)));
            }
            iwriter.WriteLine(allocDecl2(
                                         dataName,
                                         cons,
                                         PreserveHeap(minVerify),
                                         args));
            heapWriter.WriteLine(allocImpl1(
                                            dataName,
                                            ctor.Name,
                                            ctorName,
                                            cons,
                                            parms,
                                            args,
                                            (12 + 4 * sorted.Count).ToString(),
                                            (12 + 4 * ints.Count).ToString(),
                                            triggers,
                                            lemma));
            for (int i = 0; i < ints.Count; i++)
            {
                heapWriter.WriteLine(allocImplInt(
                                                  dataName,
                                                  ctorName,
                                                  ints[i].Name,
                                                  (12 + IPSize + 4 * i).ToString()));
            }
            for (int i = 0; i < ptrs.Count; i++)
            {
                heapWriter.WriteLine(allocImplPtr(
                                                  dataName,
                                                  ctorName,
                                                  ptrs[i].Name,
                                                  (RegAlloc.stackGcOffset + 16 + IPSize + 4 * i).ToString() + "/* stackGcOffset + 16 + IPSize + " + (4 * i) + " */"));
            }
            heapWriter.WriteLine(allocImpl2(
                                            dataName,
                                            ctorName,
                                            (RegAlloc.stackGcOffset + 12 + IPSize).ToString() + "/* stackGcOffset + 12 + IPSize */"));

            for (int i = 0; i < sorted.Count; i++)
            {
                var formal = sorted[i];
                iwriter.WriteLine(loadField(
                                            dataName,
                                            dataIs(ctorName),
                                            formal.Name));
                if (IsPtrType(app.AppType(formal.Type)))
                {
                    
                    
                    iwriter.WriteLine("ensures  HeapAbsData(heap, $absMem_old[abs]["
                        + (3 + i) + "]) == Abs_" + TypeString(app.AppType(formal.Type))
                        + "(" + formal.Name + (isSeq ? "_" : "#") + ctorName + "(data));");
                    iwriter.WriteLine("ensures  HeapValue(objLayouts_old, true, $toAbs_old, r.regs[x], $absMem_old[abs]["
                        + (3 + i) + "]);");
                    if (DafnySpec.IsArrayType(app.AppType(formal.Type)))
                    {
                        iwriter.WriteLine("ensures  $absMem_old[abs][" + (3+i) + "] == " + formal.Name + "#" + ctorName + "(data).arrAbs;");
                    }
                }
                else
                {
                    
                    iwriter.WriteLine("ensures  " + CompileBase.IntEqTyped(
                        app.AppType(formal.Type), formal.Name + (isSeq ? "_" : "#") + ctorName + "(data)", "r.regs[x]")
                        + ";");
                }
                heapWriter.WriteLine("implementation loadField_" + dataName + "_" + formal.Name
                    + "(my r_old:regs, const my core_state:core_state, const linear stk:mem, const linear statics:mem, const linear io:IOState, linear mems_old:mems, $commonVars:commonVars, $gcVars:gcVars, $toAbs:[int]int, $absMem:[int][int]int, $stacksFrames:[int]Frames, objLayouts:[int]ObjLayout, heap:Heap, x:int, y:opn_mem, data:"
                    + dataName + ", abs:int, obj:int)");
                heapWriter.WriteLine("    returns(my r:regs, linear mems:mems)");
                heapWriter.WriteLine("{");
                heapWriter.WriteLine("    assert THeapValue(objLayouts, true, $toAbs, obj, abs);");
                heapWriter.WriteLine("    assert THeapInv($absMem, objLayouts, heap);");
                heapWriter.WriteLine("    call r, mems := gcLoadField(r_old, core_state, stk, statics, io, mems_old, $commonVars, $gcVars, $absMem, $toAbs, $stacksFrames, objLayouts,");
                heapWriter.WriteLine("        x, y, obj - 4, " + (3 + i) + ");");
                heapWriter.WriteLine("    assert THeapValue(objLayouts, true, $toAbs, r.regs[x], $absMem[abs][" + (3 + i) + "]);");
                heapWriter.WriteLine("}");
            }
        }
    }
예제 #3
0
    void CompileDatatype1Code(Type t, TypeApply app)
    {
        
        string dataName = app.AppName(); 
        List<DatatypeCtor> ctors = compileDatatypes[app].AsDatatype.Ctors;
        bool isSeq = dataName.StartsWith("Seq_");

        
        
        for (int i = 0; i < ctors.Count; i++)
        {
            heapIWriter.WriteLine("const Tag_" + dataName + "_" + ctors[i].Name + ":int := " + (i + 1) + ";");
        }

        
        
        
        
        
        
        heapWriter.WriteLine("function HeapWordInv_" + dataName + "(absData:[int]AbsData, objLayout:ObjLayout, wordMem:[int]int, data:" + dataName + "):bool");
        heapWriter.WriteLine("{");
        heapWriter.WriteLine("    true");

        foreach (var ctor in ctors)
        {
            var ints = ctor.Formals.Where(x => !IsPtrType(app.AppType(x.Type))).ToList();
            var ptrs = ctor.Formals.Where(x =>  IsPtrType(app.AppType(x.Type))).ToList();
            var sorted = ints.Concat(ptrs).ToList();
            string ctorName = Compile_Constructor(t, ctor.Name, app.typeArgs).AppName();

            
            
            string wordMems = "";
            for (int i = 0; i < sorted.Count; i++)
            {
                heapIWriter.WriteLine("const Offset_" + dataName + "_" + sorted[i].Name + ":int := " + (8 + 4 * i) + ";");
                if (IsPtrType(app.AppType(sorted[i].Type)))
                {
                    wordMems += " && absData[wordMem[" + (3 + i) + "]] == Abs_"
                        + TypeString(app.AppType(sorted[i].Type)) + "(" + sorted[i].Name
                        + (isSeq ? "_" : "#") + ctorName + "(data))";
                }
                else
                {
                    wordMems += " && " + CompileBase.IntEqTyped(
                        app.AppType(sorted[i].Type),
                        sorted[i].Name + (isSeq ? "_" : "#") + ctorName + "(data)",
                        "wordMem[" + (3 + i) + "]");
                }
            }

            
            string dataIs = isSeq ? ("is_" + ctorName + "(data)") : "data is " + ctorName;
            heapWriter.WriteLine("&& (" + dataIs + " ==> objLayout == ObjLayout("
                + (3 + sorted.Count) + ", " + (3 + ints.Count)
                + ") && wordMem[2] == Tag_" + dataName + "_" + ctor.Name + wordMems + ")");
        }

        heapWriter.WriteLine("}");
    }
예제 #4
0
    public void CompileDatatype1Ghost(Type t, TypeApply app, TextWriter writer, TextWriter iwriter)
    {
        // type List = Nil() | Cons(hd:int, tl:List);
        string dataName = app.AppName(); // List
        List<DatatypeCtor> ctors = compileDatatypes[app].AsDatatype.Ctors;
        bool isSeq = dataName.StartsWith("Seq_");
        if (isSeq)
        {
            iwriter.WriteLine("type " + dataName + ";");
        }
        (isSeq ? writer : iwriter).WriteLine(
            "type " + (isSeq ? "implementation" : "") + "{:overload} " + dataName + " = "
            + String.Join(" | ", ctors.Select(c => Compile_Constructor(t, c.Name, app.typeArgs).AppName() + "("
                + String.Join(", ", c.Formals.Select(f => f.Name + ":" + TypeString(app.AppType(f.Type))))
                + ")")) + ";");

        if (isSeq)
        {
            foreach (var c in ctors)
            {
                string cName = Compile_Constructor(t, c.Name, app.typeArgs).AppName();
                string args = String.Join(", ", c.Formals.Select(f => f.Name));
                string parms = String.Join(", ", c.Formals.Select(f => f.Name + ":" 
                    + TypeString(app.AppType(f.Type))));
                iwriter.WriteLine("function _" + cName + "(" + parms + "):" + dataName + ";");
                writer.WriteLine("function implementation _" + cName + "(" + parms + "):"
                    + dataName + " { " + cName + "(" + args + ") }");
                foreach (var f in c.Formals)
                {
                    string tName = TypeString(app.AppType(f.Type));
                    iwriter.WriteLine("function " + f.Name + "_" + cName + "(x:" + dataName
                        + "):" + tName + ";");
                    writer.WriteLine("function implementation " + f.Name + "_" + cName + "(x:" + dataName
                        + "):" + tName + " { " + f.Name + "#" + cName + "(x) }");
                }
                iwriter.WriteLine("function is_" + cName + "(x:" + dataName + "):bool;");
                writer.WriteLine("function implementation is_" + cName + "(x:" + dataName
                    + "):bool { x is " + cName + " }");
            }
        }
    }
예제 #5
0
 public Type AppType(Type t)
 {
     return(typeApply.AppType(t));
 }