In many parts of the spec, we evaluate predicates with varying levels of complexity, such as is_ancestor_descendant_relationship or is_justified_checkpoint, which are defined recursively in the original python code, and via fold in the spec.
To ease model checking, it might be simpler to compute the entire predicate (e.g. as a function) at once, and refer to that singular function everywhere else in the spec where the predicate is used.
In the case that we extend the spec with protocol behavior (e.g. sending a message), we could update these predicates after each step (e.g. each new vote message may extend the set of justified predicates by all checkpoints between its source and target)
In many parts of the spec, we evaluate predicates with varying levels of complexity, such as
is_ancestor_descendant_relationship
oris_justified_checkpoint
, which are defined recursively in the original python code, and via fold in the spec. To ease model checking, it might be simpler to compute the entire predicate (e.g. as a function) at once, and refer to that singular function everywhere else in the spec where the predicate is used. In the case that we extend the spec with protocol behavior (e.g. sending a message), we could update these predicates after each step (e.g. each new vote message may extend the set of justified predicates by all checkpoints between its source and target)