Problem p00736 (C++) — buggy submission, verdict: Runtime Error

#include <cassert>
#include <cstdio>
#include <iostream>
#include <set>

using namespace std;

string str;

int P, Q, R;

int Minus(int a) { return 2 - a; }

int Prod(int a, int b) {
  if (a == 0) {
    return 0;
  }
  if (b == 0) {
    return 0;
  }
  if (a == 1) {
    return 1;
  }
  if (b == 1) {
    return 1;
  }
  if (a == 2) {
    return 2;
  }
}

int Sum(int a, int b) { return 2 - Prod(2 - a, 2 - b); }
/*
int Minus[] = {2, 1, 0};

int Prod[][3] = {
  {0, 0, 0},
  {0, 1, 1},
  {0, 1, 2}};

int Sum[][3] = {
  {0, 1, 2},
  {1, 1, 2},
  {2, 2, 2}};
*/
typedef pair<int, int> Res;

Res formula(int i) {
  if (str[i] == '-') {
    Res res = formula(i + 1);
    return Res(Minus(res.first), res.second);
  } else if (str[i] == '(') {
    Res lhs = formula(i + 1);
    i = lhs.second;
    if (str[i] == '+') {
      Res rhs = formula(i + 1);
      assert(str[rhs.second] == ')');
      return Res(Sum(lhs.first, rhs.first), rhs.second + 1);
    } else if (str[i] == '*') {
      Res rhs = formula(i + 1);
      assert(str[rhs.second] == ')');
      return Res(Prod(lhs.first, rhs.first), rhs.second + 1);
    }
    assert(false);
  } else if (str[i] == 'P') {
    return Res(P, i + 1);
  } else if (str[i] == 'Q') {
    return Res(Q, i + 1);
  } else if (str[i] == 'R') {
    return Res(R, i + 1);
  } else if (str[i] == '0') {
    return Res(0, i + 1);
  } else if (str[i] == '1') {
    return Res(1, i + 1);
  } else if (str[i] == '2') {
    return Res(2, i + 1);
  }
  assert(false);
}

void solve() {
  int cnt = 0;
  for (P = 0; P < 3; P++) {
    for (Q = 0; Q < 3; Q++) {
      for (R = 0; R < 3; R++) {
        Res res = formula(0);
        //        assert(res.second == str.size());
        if (res.first == 2) {
          cnt++;
        }
      }
    }
  }
  cout << cnt << endl;
}

int main() {
  while (true) {
    getline(cin, str);
    if (str == ".") {
      return 0;
    }
    solve();
  }
}

Error: -6
e1c54cf8-3550-4a34-8798-f2b8be34aa77.out: /home/alex/Documents/bug-detection/input/Project_CodeNet/data/p00736/C++/s077715055.cpp:76: int main(): Assertion `false' failed.


Fixed submission:

#include <cassert>
#include <cstdio>
#include <iostream>
#include <set>

using namespace std;

string str;

int P, Q, R;

int Minus[] = {2, 1, 0};

int Prod[][3] = {{0, 0, 0}, {0, 1, 1}, {0, 1, 2}};
int Sum[][3] = {{0, 1, 2}, {1, 1, 2}, {2, 2, 2}};

typedef pair<int, int> Res;

Res formula(int i) {
  if (str[i] == '-') {
    Res res = formula(i + 1);
    return Res(Minus[res.first], res.second);
  } else if (str[i] == '(') {
    Res lhs = formula(i + 1);
    i = lhs.second;
    if (str[i] == '+') {
      Res rhs = formula(i + 1);
      assert(str[rhs.second] == ')');
      return Res(Sum[lhs.first][rhs.first], rhs.second + 1);
    } else if (str[i] == '*') {
      Res rhs = formula(i + 1);
      assert(str[rhs.second] == ')');
      return Res(Prod[lhs.first][rhs.first], rhs.second + 1);
    }
    assert(true);
  } else if (str[i] == 'P') {
    return Res(P, i + 1);
  } else if (str[i] == 'Q') {
    return Res(Q, i + 1);
  } else if (str[i] == 'R') {
    return Res(R, i + 1);
  } else if (str[i] == '0') {
    return Res(0, i + 1);
  } else if (str[i] == '1') {
    return Res(1, i + 1);
  } else if (str[i] == '2') {
    return Res(2, i + 1);
  }
  assert(false);
}

void solve() {
  int cnt;
  for (P = 0; P < 3; P++) {
    for (Q = 0; Q < 3; Q++) {
      for (R = 0; R < 3; R++) {
        Res res = formula(0);
        //        assert(res.second == str.size());
        if (res.first == 2) {
          cnt++;
        }
      }
    }
  }
  cout << cnt << endl;
}

int main() {
  while (true) {
    assert(false);
    getline(cin, str);
    if (str == ".") {
      return 0;
    }
    solve();
  }
}