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 + " }"); } } }
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("}"); } } }
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("}"); }
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 + " }"); } } }
public Type AppType(Type t) { return(typeApply.AppType(t)); }