3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-07 19:51:22 +00:00
z3/src/util/state_graph.h
Margus Veanes af54a79acc
fixing issue #4651 (#4666)
* fixing issue #4651

* regression fix

* fix #4662

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* na

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* reenabled lift_ites_throttled with an additional filter, without the filter finding the model in report #4651 goes from .02s to 20s, also updated pretty printing of regexes to be more accurate

* removing temp testing variable

* Allow to skip System.loadLibrary() calls from Java Native class (#4667)

* using intended utility methods for sort detection

* adding ack/model

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* add smt params dependency

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* missing file

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* deps

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* order

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* persist fields

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* dbg build

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* reset caches

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* sr

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix cmake build

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* shuffle dependencies

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* warnings /errors

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* update include

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* missing cmakelists

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* update cmake

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* add depend

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* add depend

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* virtual method

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* path

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* move parameters from ast/rewriter to params

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* move fpa

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix warnings

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* remove pragma

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* dbg

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* updated sat_smt

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* na

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix #4651

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* encoding options #4665

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* expose name inclusion as optional

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix misc issues around #4661 introduced when adding lazy push/pop to selected theories

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* remove lazy push from theory_lra

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* na

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix dotnet build

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* na

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* release nodes

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* free memory in egraph

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* avoid duplicate class names frame in sat_scc and sat_smt

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* adding euf

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* elaborate on smt/drat format outline, expose euf mode as config

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* mk-var during copy

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* move theory_var_list into id_var_list and utilities from smt-enode into it, prepare for theory variables in egraph

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* with bounded

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* na

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* Remove duplicate binary condition. Fixes #4668.

* butterfly effect on fp?

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* prepare for theory plugins

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* file

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* build fix

* remove SMTFD

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* na

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* na

* na

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* na

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* na

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* na

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* na

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* na

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* na

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* SMTFD is back (#4676)

* fixing issue #4651

* regression fix

* reenabled lift_ites_throttled with an additional filter, without the filter finding the model in report #4651 goes from .02s to 20s, also updated pretty printing of regexes to be more accurate

* removing temp testing variable

* using intended utility methods for sort detection

* misc edits related to nonground regexes

* bug fix of state id off by 1 calculation error and improved pretty printing with regex tooltip generated in dgml state graph

* removed unused method declaration

* improved id to regex value map info in generated dgml

* reorgd callback function for state pretty printer

* updated some comments

Co-authored-by: Nikolaj Bjorner <nbjorner@microsoft.com>
Co-authored-by: Sergey Vladimirov <vlsergey@gmail.com>
Co-authored-by: Christoph M. Wintersteiger <cwinter@microsoft.com>
Co-authored-by: Arie Gurfinkel <arie.gurfinkel@gmail.com>
2020-09-08 04:13:18 -07:00

215 lines
7.1 KiB
C++

/*++
Copyright (c) 2020 Microsoft Corporation
Module Name:
state_graph.h
Abstract:
Data structure for incrementally tracking "live" and "dead" states in an
abstract transition system.
Author:
Caleb Stanford (calebstanford-msr / cdstanford) 2020-7
--*/
#pragma once
#include "util/map.h"
#include "util/uint_set.h"
#include "util/union_find.h"
#include "util/vector.h"
/*
state_graph
Data structure which is capable of incrementally tracking
live states and dead states.
"States" are integers. States and edges are added to the data
structure incrementally.
- States can be marked as "live" or "done".
"Done" signals that (1) no more outgoing edges will be
added and (2) the state will not be marked as live. The data
structure then tracks
which other states are live (can reach a live state), dead
(can't reach a live state), or neither.
- Some edges are labeled as not contained in a cycle. This is to
optimize search if it is known by the user of the structure
that no cycle will ever contain this edge.
Internally, we use union_find to identify states within an SCC,
and incrementally update SCCs, while propagating backwards
live and dead SCCs.
*/
class state_graph {
public:
/* Wrapper for custom callback function for pretty printing states */
struct state_pp {
/* Pointer to object that owns m_pp_state, it must be passed as the first argument to m_pp_state */
void* m_printer;
/* Pointer to function that pretty prints a state label into the stream (html-encoded if the last argument is true) */
void (*m_pp_state)(void*, std::ostream&, unsigned, bool);
state_pp(
/* Pointer to object that owns f */
void* p,
/* Pointer to function that pretty prints a state label into the stream (html-encoded if the last argument is true) */
void (*f)(void*, std::ostream&, unsigned, bool)) : m_printer(p), m_pp_state(f) {}
/* call back to m_printer using m_pp_state to pretty print state_id to the given stream (html-encoded by default) */
std::ostream& pp_state_label(std::ostream& out, unsigned state_id, bool html_encode = true) const {
if (m_printer && m_pp_state)
(*m_pp_state)(m_printer, out, state_id, html_encode);
return out;
}
};
typedef unsigned state;
typedef uint_set state_set;
typedef u_map<state_set> edge_rel;
typedef basic_union_find state_ufind;
private:
/*
All states are internally exactly one of:
- live: known to reach a live state
- dead: known to never reach a live state
- unknown: all outgoing edges have been added, but the
state is not known to be live or dead
- unexplored: not all outgoing edges have been added
As SCCs are merged, some states become aliases, and a
union find data structure collapses a now obsolete
state to its current representative. m_seen keeps track
of states we have seen, including obsolete states.
*/
state_set m_live;
state_set m_dead;
state_set m_unknown;
state_set m_unexplored;
state_set m_seen;
state_ufind m_state_ufind;
/*
Edges are saved in both from and to maps.
A subset of edges are also marked as possibly being
part of a cycle by being stored in m_sources_maybecycle.
*/
edge_rel m_sources;
edge_rel m_targets;
edge_rel m_sources_maybecycle;
/*
Pretty printer for states
*/
state_pp m_state_pp;
/*
CLASS INVARIANTS
*** To enable checking invariants, run z3 with -dbg:state_graph
(must also be in debug mode) ***
State invariants:
- live, dead, unknown, and unexplored form a partition of
the set of roots in m_state_ufind
- all of these are subsets of m_seen
- everything in m_seen is an integer less than the number of variables
in m_state_ufind
Edge invariants:
- all edges are between roots of m_state_ufind
- m_sources and m_targets are converses of each other
- no self-loops
- m_sources_maybecycle is a subrelation of m_sources
Relationship between states and edges:
- every state with a live target is live
- every state with a dead source is dead
- every state with only dead targets is dead
- there are no cycles of unknown states on maybecycle edges
*/
#ifdef Z3DEBUG
bool is_subset(state_set set1, state_set set2) const;
bool is_disjoint(state_set set1, state_set set2) const;
bool check_invariant() const;
/*
Output the whole state graph in dgml format into the file '.z3-state-graph.dgml'
*/
bool write_dgml();
/*
Output the whole state graph in dot format into the file '.z3-state-graph.dot'
*/
bool write_dot();
#endif
/*
'Core' functions that modify the plain graph, without
updating SCCs or propagating live/dead state information.
These are for internal use only.
*/
void add_state_core(state s); // unexplored + seen
void remove_state_core(state s); // unknown + seen -> seen
void mark_unknown_core(state s); // unexplored -> unknown
void mark_live_core(state s); // unknown -> live
void mark_dead_core(state s); // unknown -> dead
void add_edge_core(state s1, state s2, bool maybecycle);
void remove_edge_core(state s1, state s2);
void rename_edge_core(state old1, state old2, state new1, state new2);
state merge_states(state s1, state s2);
state merge_states(state_set& s_set);
/*
Algorithmic search routines
- live state propagation
- dead state propagation
- cycle / strongly-connected component detection
*/
void mark_live_recursive(state s);
bool all_targets_dead(state s);
void mark_dead_recursive(state s);
state merge_all_cycles(state s);
public:
state_graph(state_pp p):
m_live(), m_dead(), m_unknown(), m_unexplored(), m_seen(),
m_state_ufind(), m_sources(), m_targets(), m_sources_maybecycle(), m_state_pp(p)
{
CASSERT("state_graph", check_invariant());
}
/*
Exposed methods
These methods may be called in any order, as long as:
- states are added before edges are added between them
- outgoing edges are not added from a done state
- a done state is not marked as live
- edges are not added creating a cycle containing an edge with
maybecycle = false (this is not necessary for soundness, but
prevents completeness for successfully detecting dead states)
*/
void add_state(state s);
void add_edge(state s1, state s2, bool maybecycle);
void mark_live(state s);
void mark_done(state s);
bool is_seen(state s) const;
bool is_live(state s) const;
bool is_dead(state s) const;
bool is_done(state s) const;
unsigned get_size() const;
/*
Pretty printing
*/
std::ostream& display(std::ostream& o) const;
};