% -*- prolog -*-

% We are trying to prove that a formula P is an invariant for a system M.
% This is the case if there exists a k for which P is k-inductive.
invariant(M, P) <= transitionSystem(M), 
                   kInductive(M, P, K).

% P is k-inductive if it holds up to step k (using bmc), and if the induction holds
kInductive(M, P, K) <= bmc(M, P, K), inductionStep(M, P, K).

bmc(M, P, K) <= yicesBmcFormula(M, P, K, F), yicesUnsat(F).
inductionStep(M, P, K) <= yicesInductionFormula(M, P, K, F), yicesUnsat(F).

% The above gives us a proof that P is an invariant if we know k. 
% We can search for k iteratively. iterInductive looks for all the k for
% which the property is k-inductive upto a given bound
iterInductive(M, P, K, U) :- in_range(1, U, K), kInductive(M, P, K).

% We can derive that P is an invariant using iterInductive
invariant(M, P) :- transitionSystem(M), 
                   iterInductive(M, P, K, 5).

% Shortcut for yices
yicesUnsat(F) <= yices(F, R), equal(R, 'unsat').
