private void PrintCounterexampleHelper()

in Sources/VeriSol/VeriSolExecuter.cs [287:366]


        private void PrintCounterexampleHelper(List<Tuple<string, string>> trace)
        {
            Stack<string> callStack = new Stack<string>();
            string currentArgs = "";
            bool collectArgs = false;
            List<string> resultArray = new List<string>();

            // this is a list of (line#, element)
            // element \in {CALL foo, RETURN from foo, x = e, ASSERTION FAILS, ...}
            for (int i = 0; i < trace.Count(); i++)
            {
                var elem = trace[i].Item2;
                if (elem.StartsWith("CALL CorralChoice_"))
                {
                    continue;
                }
                else if (elem.StartsWith("RETURN from CorralChoice_"))
                {
                    continue;
                }
                else if (elem.StartsWith("CALL "))
                {
                    var func = elem.Substring("CALL ".Length);
                    callStack.Push(func);
                    currentArgs = "";
                }
                else if (elem.StartsWith("RETURN from "))
                {
                    var func = elem.Substring("RETURN from ".Length);
                    Debug.Assert(callStack.Count > 0, "Call stack cannot be empty");
                    Debug.Assert(func.TrimEnd().Equals(callStack.Peek().TrimEnd()), $"Top of stack {callStack.Peek()} does not match with return {func}");
                    callStack.Pop();
                }
                else if (elem.StartsWith("_verisolFirstArg"))
                {
                    collectArgs = true;
                }
                else if (elem.StartsWith("_verisolLastArg"))
                {
                    Debug.Assert(callStack.Count > 0, "callstack cannot be empty");
                    collectArgs = false;
                    if (callStack.Count == 1)
                    {
                        resultArray.Add($"{trace[i].Item1}: {ConvertFunctionName(callStack.Peek())} ({currentArgs.Substring(", ".Length)})");
                    }
                }
                else if (elem.StartsWith("(ASSERTION FAILS"))
                {
                    resultArray.Add($"{trace[i].Item1}: ASSERTION FAILS!");
                }
                else if (elem.Contains("=") && !elem.Contains("=="))
                {

                    if (collectArgs)
                    {
                        // Replace "T@Ref!val!0" with "address!0"
                        string[] splitElem = elem.Split(" = ");
                        Debug.Assert(splitElem.Count() == 2);
                        string[] rhsSplit = splitElem[1].Split("!");
                        if (rhsSplit.Count() > 0 && rhsSplit[0].Equals("T@Ref"))
                        {
                            currentArgs += ", " + elem.Replace("T@Ref!val", "address");
                        }
                        else
                        {
                            currentArgs += ", " + elem;
                        }                       
                    }
                }
                else
                {
                    Debug.Assert(false, $"This should be unreachable, found a new class of statement {elem}");
                }
            }

            resultArray.ForEach(x => Console.WriteLine(x));
            // Only printing counterexample on the command line:
            File.WriteAllLines(counterexampleFileName, resultArray);
            return;
        }