//internal RaiseRule<Expr> haltRule; public VarInfo(STBuilderZ3 stb, Symtab stab, iterexpr ie, Sort charsort) { this.stab = stab; this.charsort = charsort; this.stb = stb; this.binder = ie.binder; binderid = stab.Get(ie.binder).id; bekVarIds = new List <int>(); bekVarVals = new List <Expr>(); bekVarSorts = new List <Sort>(); proj = new Dictionary <int, int>(); int regPosNr = 0; foreach (iterassgn ia in IterInfo.Initializers(ie, stab)) { proj[stab.Get(ia.lhs).id] = regPosNr; bekVarIds.Add(stab.Get(ia.lhs).id); bekVarVals.Add(MkExpr(stab.Get(ia.lhs).type, ia.rhs)); bekVarSorts.Add(BekTypeToSort(stab.Get(ia.lhs).type)); regPosNr += 1; } K = bekVarSorts.Count; //register sort regSort = (K == 0 ? stb.Solver.UnitSort : (K == 1 ? bekVarSorts[0] : stb.Solver.MkTupleSort(bekVarSorts.ToArray()))); //initial register value initReg = (K == 0 ? stb.Solver.UnitConst : (K == 1 ? bekVarVals[0] : stb.Solver.MkTuple(bekVarVals.ToArray()))); //input character variable c = this.stb.MkInputVariable(charsort); //register variable r = this.stb.MkRegister(regSort); //maps variable identifiers used in the bek program to corresponding term variables varMap = new Dictionary <int, Expr>(); varMap[binderid] = c; //input character variable for (int i = 0; i < K; i++) //bek pgm variables { varMap[bekVarIds[i]] = (K == 1 ? r : stb.Solver.MkProj(i, r)); } //haltRule = new RaiseRule<Expr>(); }
public static HessForcInfo GetCoarseHessForcSubSimple (object[] atoms , HessMatrix hess , Vector[] forc , List <int>[] lstNewIdxRemv , double thres_zeroblk , ILinAlg ila , bool cloneH , string[] options // { "pinv(D)" } ) { HessMatrix H = hess; Vector F = forc.ToVector(); if (cloneH) { H = H.CloneHess(); } bool process_disp_console = false; bool parallel = true; for (int iter = lstNewIdxRemv.Length - 1; iter >= 0; iter--) { //int[] ikeep = lstNewIdxRemv[iter].Item1; int[] iremv = lstNewIdxRemv[iter].ToArray(); int iremv_min = iremv.Min(); int iremv_max = iremv.Max(); HDebug.Assert(H.ColBlockSize == H.RowBlockSize); int blksize = H.ColBlockSize; //HDebug.Assert(ikeep.Max() < blksize); //HDebug.Assert(iremv.Max() < blksize); //HDebug.Assert(iremv.Max()+1 == blksize); //HDebug.Assert(iremv.Max() - iremv.Min() + 1 == iremv.Length); int[] idxkeep = HEnum.HEnumFromTo(0, iremv_min - 1).ToArray(); int[] idxremv = HEnum.HEnumFromTo(iremv_min, iremv_max).ToArray(); //HDebug.Assert(idxkeep.HUnionWith(idxremv).Length == blksize); IterInfo iterinfo = new IterInfo(); iterinfo.sizeHessBlkMat = idxremv.Max() + 1; // H.ColBlockSize; iterinfo.numAtomsRemoved = idxremv.Length; iterinfo.time0 = DateTime.UtcNow; //////////////////////////////////////////////////////////////////////////////////////// // make C sparse double C_density0; double C_density1; { double thres_absmax = thres_zeroblk; C_density0 = 0; List <Tuple <int, int> > lstIdxToMakeZero = new List <Tuple <int, int> >(); foreach (var bc_br_bval in H.EnumBlocksInCols(idxremv)) { int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; var bval = bc_br_bval.Item3; if (br >= iremv_min) { // bc_br is in D, not in C continue; } C_density0++; double absmax_bval = bval.HAbsMax(); if (absmax_bval < thres_absmax) { lstIdxToMakeZero.Add(new Tuple <int, int>(bc, br)); } } C_density1 = C_density0 - lstIdxToMakeZero.Count; foreach (var bc_br in lstIdxToMakeZero) { int bc = bc_br.Item1; int br = bc_br.Item2; HDebug.Assert(bc > br); var Cval = H.GetBlock(bc, br); var Dval = H.GetBlock(bc, bc); var Aval = H.GetBlock(br, br); var Bval = Cval.Tr(); H.SetBlock(bc, br, null); // nCval = Cval -Cval H.SetBlock(bc, bc, Dval + Cval); // nDval = Dval - (-Cval) = Dval + Cval // nBval = Bval -Bval H.SetBlock(br, br, Aval + Bval); // nAval = Aval - (-Bval) = Aval + Bval } iterinfo.numSetZeroBlock = lstIdxToMakeZero.Count; iterinfo.numNonZeroBlock = (int)C_density1; C_density0 /= (idxkeep.Length * idxremv.Length); C_density1 /= (idxkeep.Length * idxremv.Length); } //////////////////////////////////////////////////////////////////////////////////////// // get A, B, C, D HessMatrix A = H.SubMatrixByAtoms(false, idxkeep, idxkeep); HessMatrix B = H.SubMatrixByAtoms(false, idxkeep, idxremv); HessMatrix C = H.SubMatrixByAtoms(false, idxremv, idxkeep); HessMatrix D = H.SubMatrixByAtoms(false, idxremv, idxremv); Vector nF; Vector nG; { nF = new double[idxkeep.Length * 3]; nG = new double[idxremv.Length * 3]; for (int i = 0; i < idxkeep.Length * 3; i++) { nF[i] = F[i]; } for (int i = 0; i < idxremv.Length * 3; i++) { nG[i] = F[i + nF.Size]; } } Matlab.PutMatrix("A", A, true); Matlab.PutMatrix("B", B, true); Matlab.PutMatrix("C", C, true); Matlab.PutMatrix("D", D, true); Matlab.PutVector("F", nF); Matlab.PutVector("G", nG); //////////////////////////////////////////////////////////////////////////////////////// // Get B.inv(D).C // // var BInvDC_BInvDG = Get_BInvDC_BInvDG_WithSqueeze(C, D, nG, process_disp_console // , options // , thld_BinvDC: thres_zeroblk/lstNewIdxRemv.Length // , parallel: parallel // ); // HessMatrix B_invD_C = BInvDC_BInvDG.Item1; // Vector B_invD_G = BInvDC_BInvDG.Item2; // GC.Collect(0); Matlab.Execute("BinvD = B * inv(D);"); Matlab.Execute("clear B, D;"); Matlab.Execute("BinvDC = BinvD * C;"); Matlab.Execute("BinvDG = BinvD * G;"); //////////////////////////////////////////////////////////////////////////////////////// // Get A - B.inv(D).C // F - B.inv(D).G Matlab.Execute("HH = A - BinvDC;"); Matlab.Execute("FF = F - BinvDG;"); //////////////////////////////////////////////////////////////////////////////////////// // Replace A -> H H = Matlab.GetMatrix("HH", H.Zeros, true); F = Matlab.GetVector("FF"); Matlab.Execute("clear;"); { ValueTuple <HessMatrix, Vector> BBInvDDCC_BBInvDDGG = Get_BInvDC_BInvDG_Simple (C , D , nG , process_disp_console: process_disp_console , thld_BinvDC: thres_zeroblk / lstNewIdxRemv.Length , parallel: parallel ); HessMatrix HH = A - BBInvDDCC_BBInvDDGG.Item1; Vector FF = nF - BBInvDDCC_BBInvDDGG.Item2; double dbg_HH = (HH - H).HAbsMax(); double dbg_FF = (FF - F).ToArray().MaxAbs(); HDebug.Assert(Math.Abs(dbg_HH) < 0.00000001); HDebug.Assert(Math.Abs(dbg_FF) < 0.00000001); } { ValueTuple <HessMatrix, Vector> BBInvDDCC_BBInvDDGG = Get_BInvDC_BInvDG (C , D , nG , process_disp_console: process_disp_console , options: new string[0] , thld_BinvDC: thres_zeroblk / lstNewIdxRemv.Length , parallel: parallel ); HessMatrix HH = A - BBInvDDCC_BBInvDDGG.Item1; Vector FF = nF - BBInvDDCC_BBInvDDGG.Item2; double dbg_HH = (HH - H).HAbsMax(); double dbg_FF = (FF - F).ToArray().MaxAbs(); HDebug.Assert(Math.Abs(dbg_HH) < 0.00000001); HDebug.Assert(Math.Abs(dbg_FF) < 0.00000001); } { ValueTuple <HessMatrix, Vector> BBInvDDCC_BBInvDDGG = Get_BInvDC_BInvDG_WithSqueeze (C , D , nG , process_disp_console: process_disp_console , options: new string[0] , thld_BinvDC: thres_zeroblk / lstNewIdxRemv.Length , parallel: parallel ); HessMatrix HH = A - BBInvDDCC_BBInvDDGG.Item1; Vector FF = nF - BBInvDDCC_BBInvDDGG.Item2; double dbg_HH = (HH - H).HAbsMax(); double dbg_FF = (FF - F).ToArray().MaxAbs(); HDebug.Assert(Math.Abs(dbg_HH) < 0.00000001); HDebug.Assert(Math.Abs(dbg_FF) < 0.00000001); } GC.Collect(); } HDebug.Assert(H.ColSize == H.RowSize); HDebug.Assert(H.ColSize == F.Size); return(new HessForcInfo { hess = H, forc = F.ToVectors(3), }); }
//public class CGetHessCoarseResiIterImpl //{ // public List<IterInfo> iterinfos = null; // public HessMatrix H = null; // public Vector F = null; //}; public static HessForcInfo GetCoarseHessForcSubIter (object[] atoms , HessMatrix hess , Vector[] forc , List <int>[] lstNewIdxRemv , double thres_zeroblk , ILinAlg ila , bool cloneH , string[] options // { "pinv(D)" } ) { HessMatrix H = hess; Vector F = forc.ToVector(); ila = null; if (cloneH) { H = H.CloneHess(); } bool process_disp_console = true; if (options != null && options.Contains("print process")) { process_disp_console = true; } bool parallel = true; /// keep only lower triangle of H (lower block triangles) { HashSet <Tuple <int, int, MatrixByArr> > lstUppTrig = new HashSet <Tuple <int, int, MatrixByArr> >(); foreach (ValueTuple <int, int, MatrixByArr> bc_br_bval in H.EnumBlocks()) { int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; if (bc < br) { lstUppTrig.Add(bc_br_bval.ToTuple()); } } foreach (Tuple <int, int, MatrixByArr> bc_br_bval in lstUppTrig) { int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; HDebug.Assert(bc < br); H.SetBlock(bc, br, null); } } GC.Collect(); List <DateTime> process_time = new List <DateTime>(); //System.Console.WriteLine("begin coarse-graining"); List <IterInfo> iterinfos = new List <IterInfo>(); for (int iter = lstNewIdxRemv.Length - 1; iter >= 0; iter--) { process_time.Clear(); if (process_disp_console) { process_time.Add(DateTime.UtcNow); System.Console.Write(" - {0:000} : ", iter); } //int[] ikeep = lstNewIdxRemv[iter].Item1; int[] iremv = lstNewIdxRemv[iter].ToArray(); int iremv_min = iremv.Min(); int iremv_max = iremv.Max(); HDebug.Assert(H.ColBlockSize == H.RowBlockSize); int blksize = H.ColBlockSize; //HDebug.Assert(ikeep.Max() < blksize); //HDebug.Assert(iremv.Max() < blksize); //HDebug.Assert(iremv.Max()+1 == blksize); //HDebug.Assert(iremv.Max() - iremv.Min() + 1 == iremv.Length); int[] idxkeep = HEnum.HEnumFromTo(0, iremv_min - 1).ToArray(); int[] idxremv = HEnum.HEnumFromTo(iremv_min, iremv_max).ToArray(); //HDebug.Assert(idxkeep.HUnionWith(idxremv).Length == blksize); IterInfo iterinfo = new IterInfo(); iterinfo.sizeHessBlkMat = idxremv.Max() + 1; // H.ColBlockSize; iterinfo.numAtomsRemoved = idxremv.Length; iterinfo.time0 = DateTime.UtcNow; //////////////////////////////////////////////////////////////////////////////////////// // make C sparse double C_density0; double C_density1; { double thres_absmax = thres_zeroblk; C_density0 = 0; List <Tuple <int, int> > lstIdxToMakeZero = new List <Tuple <int, int> >(); foreach (var bc_br_bval in H.EnumBlocksInCols(idxremv)) { int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; var bval = bc_br_bval.Item3; if (br >= iremv_min) { // bc_br is in D, not in C continue; } C_density0++; double absmax_bval = bval.HAbsMax(); if (absmax_bval < thres_absmax) { lstIdxToMakeZero.Add(new Tuple <int, int>(bc, br)); } } C_density1 = C_density0 - lstIdxToMakeZero.Count; foreach (var bc_br in lstIdxToMakeZero) { int bc = bc_br.Item1; int br = bc_br.Item2; HDebug.Assert(bc > br); var Cval = H.GetBlock(bc, br); var Dval = H.GetBlock(bc, bc); var Aval = H.GetBlock(br, br); var Bval = Cval.Tr(); H.SetBlock(bc, br, null); // nCval = Cval -Cval H.SetBlock(bc, bc, Dval + Cval); // nDval = Dval - (-Cval) = Dval + Cval // nBval = Bval -Bval H.SetBlock(br, br, Aval + Bval); // nAval = Aval - (-Bval) = Aval + Bval } iterinfo.numSetZeroBlock = lstIdxToMakeZero.Count; iterinfo.numNonZeroBlock = (int)C_density1; C_density0 /= (idxkeep.Length * idxremv.Length); C_density1 /= (idxkeep.Length * idxremv.Length); } //////////////////////////////////////////////////////////////////////////////////////// // get A, B, C, D HessMatrix A = H; // HessMatrix A = H.SubMatrixByAtoms(false, idxkeep, idxkeep); // HessMatrix B = H.SubMatrixByAtoms(false, idxkeep, idxremv); HessMatrix C; // HessMatrix C = H.SubMatrixByAtoms(false, idxremv, idxkeep, parallel:parallel); HessMatrix D; // HessMatrix D = H.SubMatrixByAtoms(false, idxremv, idxremv, parallel:parallel); Vector nF; Vector nG; { C = H.Zeros(idxremv.Length * 3, idxkeep.Length * 3); D = H.Zeros(idxremv.Length * 3, idxremv.Length * 3); //List<Tuple<int, int, MatrixByArr>> lst_bc_br_bval = H.EnumBlocksInCols(idxremv).ToList(); //foreach(var bc_br_bval in lst_bc_br_bval) foreach (var bc_br_bval in H.EnumBlocksInCols(idxremv)) { int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; var bval = bc_br_bval.Item3; if (bc < br) { HDebug.Assert(false); continue; } H.SetBlock(bc, br, null); if (bc > iremv_max) { HDebug.Assert(false); continue; } if (br > iremv_max) { HDebug.Assert(false); continue; } if (br < iremv_min) { int nc = bc - iremv_min; int nr = br; HDebug.Assert(C.HasBlock(nc, nr) == false); C.SetBlock(nc, nr, bval.CloneT()); } else { int nc = bc - iremv_min; int nr = br - iremv_min; HDebug.Assert(D.HasBlock(nc, nr) == false); D.SetBlock(nc, nr, bval); if (nc != nr) { HDebug.Assert(D.HasBlock(nr, nc) == false); D.SetBlock(nr, nc, bval.Tr()); } } } HDebug.Assert(H.EnumBlocksInCols(idxremv).Count() == 0); nF = new double[idxkeep.Length * 3]; nG = new double[idxremv.Length * 3]; for (int i = 0; i < idxkeep.Length * 3; i++) { nF[i] = F[i]; } for (int i = 0; i < idxremv.Length * 3; i++) { nG[i] = F[i + nF.Size]; } } if (process_disp_console) { process_time.Add(DateTime.UtcNow); int ptc = process_time.Count; System.Console.Write("CD({0:00.00} min), ", (process_time[ptc - 1] - process_time[ptc - 2]).TotalMinutes); } //////////////////////////////////////////////////////////////////////////////////////// // Get B.inv(D).C HessMatrix B_invD_C; Vector B_invD_G; { { var BInvDC_BInvDG = Get_BInvDC_BInvDG_WithSqueeze(C, D, nG, process_disp_console , options , thld_BinvDC: thres_zeroblk / lstNewIdxRemv.Length , parallel: parallel ); B_invD_C = BInvDC_BInvDG.Item1; B_invD_G = BInvDC_BInvDG.Item2; } if (process_disp_console) { process_time.Add(DateTime.UtcNow); int ptc = process_time.Count; System.Console.Write("B.invD.C({0:00.00} min), ", (process_time[ptc - 1] - process_time[ptc - 2]).TotalMinutes); } GC.Collect(0); } //////////////////////////////////////////////////////////////////////////////////////// // Get A - B.inv(D).C /// iterinfo.numAddIgnrBlock = A.UpdateAdd(B_invD_C, -1, null, thres_zeroblk/lstNewIdxRemv.Length, parallel:parallel); { HessMatrix __this = A; HessMatrix other = B_invD_C; double _thres_NearZeroBlock = thres_zeroblk / lstNewIdxRemv.Length; int[] _count = new int[1]; int[] _count_ignored = new int[1]; //foreach(var bc_br_bval in other.EnumBlocks()) Action <ValueTuple <int, int, MatrixByArr>, object> func = delegate(ValueTuple <int, int, MatrixByArr> bc_br_bval, object func_param) { _count[0]++; int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; MatrixByArr other_bmat = bc_br_bval.Item3; if (bc < br) { return; // continue; } if (other_bmat.HAbsMax() <= _thres_NearZeroBlock) { /// other_bmat = other_bmat -other_bmat; /// other_diag = other_diag - (-other_bmat) = other_diag + other_bmat; /// this_diag = this_diat - B_invD_C /// = this_diat - other_diag /// = this_diat - (other_diag + other_bmat) /// = this_diat - other_diag - other_bmat /// = (this_diat - other_bmat) - other_diag /// = (this_diat - other_bmat) - (processed later) /// = (this_diat - other_bmat) MatrixByArr this_diag = __this.GetBlock(bc, bc); MatrixByArr new_diag = this_diag - other_bmat; __this.SetBlockLock(bc, bc, new_diag); other_bmat = null; lock (_count_ignored) _count_ignored[0]++; } if (other_bmat != null) { //if(HDebug.IsDebuggerAttached) //{ // double trace = other_bmat.Trace(); // if(bc != br && bc<2059 && br<2059 && Math.Abs(trace) > 100) // HDebug.Assert(); //} MatrixByArr this_bmat = __this.GetBlock(bc, br); if (this_bmat == null) { this_bmat = new double[3, 3]; } MatrixByArr new_bmat = this_bmat - other_bmat; __this.SetBlockLock(bc, br, new_bmat); } }; if (parallel) { HParallel.ForEach(other.EnumBlocks(), func, null); } else { foreach (var bc_br_bval in other.EnumBlocks()) { func(bc_br_bval, null); } } iterinfo.numAddIgnrBlock = _count_ignored[0]; } if (process_disp_console) { process_time.Add(DateTime.UtcNow); int ptc = process_time.Count; System.Console.Write("A-BinvDC({0:00.00} min), ", (process_time[ptc - 1] - process_time[ptc - 2]).TotalMinutes); } //HessMatrix nH = A - B_invD_C; //nH = ((nH + nH.Tr())/2).ToHessMatrix(); //////////////////////////////////////////////////////////////////////////////////////// // Replace A -> H H = A; F = nF - B_invD_G; //////////////////////////////////////////////////////////////////////////////////////// // print iteration log iterinfo.usedMemoryByte = GC.GetTotalMemory(false); iterinfo.time1 = DateTime.UtcNow; iterinfos.Add(iterinfo); if (process_disp_console) { System.Console.Write("summary(makezero {0,5}, nonzero {1,5}, numIgnMul {2,7}, numRemvAtoms {3,3}, {4,5:0.00} min, {5} mb, {6}x{6}, nzeroBlk/Atom {7:0.00}), GC(" , iterinfo.numSetZeroBlock , iterinfo.numNonZeroBlock , iterinfo.numAddIgnrBlock , iterinfo.numAtomsRemoved , iterinfo.compTime.TotalMinutes , iterinfo.usedMemoryByte / (1024 * 1024) , (idxkeep.Length * 3) , ((double)iterinfo.numNonZeroBlock / idxremv.Length) ); } GC.Collect(); if (process_disp_console) { System.Console.WriteLine(")"); } } int numca = H.ColBlockSize - lstNewIdxRemv.HListCount().Sum(); //System.Console.WriteLine("finish coarse-graining"); { int[] idxkeep = HEnum.HEnumCount(numca).ToArray(); H = H.SubMatrixByAtoms(false, idxkeep, idxkeep, false); } { H.MakeNearZeroBlockAsZero(thres_zeroblk); } { var list_bc_br_bval = H.EnumBlocks().ToArray(); Action <ValueTuple <int, int, MatrixByArr> > func = delegate(ValueTuple <int, int, MatrixByArr> bc_br_bval) { int bc = bc_br_bval.Item1; int br = bc_br_bval.Item2; var bval = bc_br_bval.Item3; HDebug.Assert(bc >= br); if (bc == br) { return; } MatrixByArr bval_tr = bval.Tr(); H.SetBlockLock(br, bc, bval_tr); HDebug.Assert(H.GetBlockLock(bc, br) == bval); }; if (parallel) { HParallel.ForEach(list_bc_br_bval, func); } else { foreach (var bc_br_bval in list_bc_br_bval) { func(bc_br_bval); } } } GC.Collect(); //System.Console.WriteLine("finish resizing"); HDebug.Assert(H.ColSize == H.RowSize); HDebug.Assert(H.ColSize == F.Size); return(new HessForcInfoIter { iterinfos = iterinfos, hess = H, forc = F.ToVectors(3), }); }
public override STModel Convert(iterexpr ie, Symtab stab) { var solver = stb.Solver; int binderid = stab.Get(ie.binder).id; List <int> bekVarIds = new List <int>(); List <Expr> bekVarVals = new List <Expr>(); List <Sort> bekVarSorts = new List <Sort>(); Dictionary <int, int> proj = new Dictionary <int, int>(); foreach (iterassgn ia in IterInfo.Initializers(ie, stab)) { proj[stab.Get(ia.lhs).id] = bekVarIds.Count; bekVarIds.Add(stab.Get(ia.lhs).id); bekVarVals.Add(MkExpr(stab.Get(ia.lhs).type, ia.rhs)); bekVarSorts.Add(BekTypeToSort(stab.Get(ia.lhs).type)); } int K = bekVarSorts.Count; //register sort Sort regSort = (K == 0 ? solver.UnitSort : (K == 1 ? bekVarSorts[0] : solver.MkTupleSort(bekVarSorts.ToArray()))); //initial register value Expr initReg = (K == 0 ? solver.UnitConst : (K == 1 ? bekVarVals[0] : solver.MkTuple(bekVarVals.ToArray()))); //input character variable Expr c = this.stb.MkInputVariable(charsort); //register variable Expr r = this.stb.MkRegister(regSort); //maps variable identifiers used in the bek program to corresponding term variables Dictionary <int, Expr> varMap = new Dictionary <int, Expr>(); varMap[binderid] = c; for (int i = 0; i < K; i++) { varMap[bekVarIds[i]] = (K == 1 ? r : solver.MkProj(i, r)); } List <Move <Rulez3> > moves = new List <Move <Rulez3> >(); Expr previousCaseNegated = solver.True; foreach (itercase curcase in ie.GetNormalCases()) { if (!solver.IsSatisfiable(previousCaseNegated)) { break; } //initial symbolic values are the previous register values Expr[] regs0 = new Expr[K]; for (int i = 0; i < K; i++) { regs0[i] = varMap[bekVarIds[i]]; } Expr[] regs = new Expr[K]; for (int i = 0; i < K; i++) { regs[i] = regs0[i]; } //gets the current symbolic value of ident Func <ident, Expr> idents = x => { SymtabElt se = stab.Get(x); if (se.id == binderid) { return(c); //the input character } return(regs0[proj[se.id]]); //the current sybolic value of x }; //current condition is the case condition and not the previous case conditions Expr casecond = this.expr_handler.Convert(curcase.cond, idents); Expr guard = stb.And(previousCaseNegated, casecond); Expr not_casecond = stb.Not(casecond); previousCaseNegated = stb.And(previousCaseNegated, solver.MkNot(casecond)); List <Expr> yields = new List <Expr>(); if (solver.IsSatisfiable(guard)) { #region iterate over the iter statements in the body foreach (iterstmt ist in curcase.body) { //gets the current symbolic value of ident //note that the symbolic value may have been updated by a previous assignment Func <ident, Expr> idents1 = x => { SymtabElt se = stab.Get(x); if (se.id == binderid) { return(c); //the input character } return(regs0[proj[se.id]]); //the current sybolic value of x }; iterassgn a = ist as iterassgn; if (a != null) { var v = expr_handler.Convert(a.rhs, idents1); regs[proj[stab.Get(a.lhs).id]] = v; } else { yieldstmt y = ist as yieldstmt; if (y != null) { foreach (var e in y.args) { strconst s = e as strconst; if (s == null) { yields.Add(expr_handler.Convert(e, idents1)); } else { foreach (int sc in s.content) { yields.Add(solver.MkNumeral(sc, charsort)); } } } } else { throw new BekException(); //TBD: undefined case } } } #endregion Expr upd = (K == 0 ? solver.UnitConst : (K == 1 ? regs[0] : solver.MkTuple(regs))); moves.Add(stb.MkRule(0, 0, guard, upd, yields.ToArray())); } } previousCaseNegated = solver.True; bool noEndCases = true; foreach (itercase curcase in ie.GetEndCases()) { noEndCases = false; if (!solver.IsSatisfiable(previousCaseNegated)) { break; } //initial symbolic values are the previous register values Expr[] regs = new Expr[K]; for (int i = 0; i < K; i++) { regs[i] = varMap[bekVarIds[i]]; } //gets the current symbolic value of ident Func <ident, Expr> idents = x => { SymtabElt se = stab.Get(x); if (se.id == binderid) { throw new BekException("Input var must not occur in an end case"); } return(regs[proj[se.id]]); //the current sybolic value of x }; //current condition is the case condition and not the previous case conditions Expr casecond = this.expr_handler.Convert(curcase.cond, idents); Expr guard = stb.And(previousCaseNegated, casecond); Expr not_casecond = stb.Not(casecond); previousCaseNegated = stb.And(previousCaseNegated, solver.MkNot(casecond)); List <Expr> yields = new List <Expr>(); if (solver.IsSatisfiable(guard)) { #region iterate over the iter statements in the body foreach (iterstmt ist in curcase.body) { //gets the current symbolic value of ident //note that the symbolic value may have been updated by a previous assignment Func <ident, Expr> idents1 = x => { SymtabElt se = stab.Get(x); if (se.id == binderid) { throw new BekException("Input var must not occur in an end case"); } return(regs[proj[se.id]]); //the current sybolic value of x }; iterassgn a = ist as iterassgn; if (a != null) { var v = expr_handler.Convert(a.rhs, idents1); regs[proj[stab.Get(a.lhs).id]] = v; } else { yieldstmt y = ist as yieldstmt; if (y != null) { foreach (var e in y.args) { strconst s = e as strconst; if (s == null) { yields.Add(expr_handler.Convert(e, idents1)); } else { foreach (int sc in s.content) { yields.Add(solver.MkNumeral(sc, charsort)); } } } } else { throw new BekException(); //TBD: undefined case } } } #endregion moves.Add(stb.MkFinalOutput(0, guard, yields.ToArray())); } } //if no end cases were given, assume default true end case with empty yield if (noEndCases) { moves.Add(stb.MkFinalOutput(0, solver.True)); } STModel iterST = STModel.Create(solver, "iter", initReg, charsort, charsort, regSort, 0, moves); iterST.Simplify(); return(iterST); }