I wrote two versions, one in C++, using dynamic programming/memoizing, and another in Prolog, not using it, so they are not directly comparable.
C++:
#include <iostream>
#include <vector>
const unsigned long N = 4294967296;
bool terminates(unsigned long x) { // x should be less than N
    std::vector<bool> visited(N, false);
    while(x != 77) {
        if(visited[x])
            return false;
        visited[x] = true;
        x = (x*12367+3466) % N;
    }
    return true;
}
int main() {
    std::cout << terminates(819688) << std::endl; // prints 0
    std::cout << terminates(955725) << std::endl; // prints 1
}
This finishes in 7s.
Prolog:
The idea behind the non-memoizing version is to loop only N+1 steps. If it doesn't terminate before then, it doesn't terminate at all, since there are only N states.
terminates(X, R) :- terminates(X, 4294967297, R).
terminates(77, _, true) :- !.
terminates(_, 0, false) :- !.
terminates(_, I, false) :- I =< 0, !.
terminates(X, I, R) :-
    I2 is I-1,
    X2 is (X*12367+3466) mod 4294967296,
    terminates(X2, I2, R).
The first of these queries takes much longer:
?- terminates(819688, R).
R = false.
?- terminates(955725, R).
R = true.
One could do memoizing in Prolog, obviously, using table or assertz, but I think you would run into memory problems much sooner than C++. C++'s vector<bool> uses just 1 bit per element! (Using unordered_map here would be a mistake, as it has slower lookup and uses much more memory)