Skip to content

Conversation

@merkste
Copy link
Contributor

@merkste merkste commented Mar 9, 2018

After certain replacements, e.g., formula substitution, the AST becomes a directed acyclic graph. On copying we want to preserve this structure. The identification of duplicates is non-local since duplicates may appear everywhere in the AST/DAG.

Significance

Certain more complex models that feature nested formulas cannot be handled with reasonable time and memory bounds with the current traversal and copying implementation. In one case-study this makes the difference between building and model-checking in a few seconds and running out of time and 16g memory right after parsing the input file. Even syntax-highlighting does not work at all.

Structure

This PR consists of three logical parts.

  1. Small refactoring of ExpressionQuant hierarchy to avoid code duplicates
  2. Introduction of a visitor that keeps track of the nodes already visited
  3. Implementation of deep-copying that does not unfold the AST's DAG structure

Changes to ASTTraverse / ASTTraverseModify

Part 2 introduces a new root class for AST traversal, DAGVisitor that keeps track of visited nodes. The method visit now visits only nodes never seen before. If a new node is seen, the newly introduced method visitNow is called. Subclasses have to override this method instead of visit to implement their behavior. If they decide to visit node, they should call visit. There are no changes to visitPre and visitPost For the complete ASTTraverse and ASTTraverseModify hierarchy this is already done. Hence adaption of visitors in existing branches is done by simply renaming their implementation of visit to visitNow. Furthermore, if needed, the duplicate identification can be turned off which leads to the old behavior of visiting nodes multiple times.

For details, please see commits

  • 98228f0 [DAG-visit] Implement DAG-aware visitor and
  • 48a14d1 [DAG-visit] Adapt existing visitors to be DAG-aware

Changes to deep copying

Part 3 splits deep-copying into two steps. First, creating a shallow copy of an AST node by calling clone. Second, copying sub-nodes of the clone using deepCopy with the DeepCopy visitor.
This is already implemented for all ASTElement classes. Newly created ASTElements are only required to provide an implementation of clone and deepCopy(DeepCopy copier) instead of the old monolithic deepCopy(). Nothing else changes.

For details, please see commit

  • 802a5a6 [DAG-copy] Implement deep-copying the AST without unfolding the DAG

@merkste
Copy link
Contributor Author

merkste commented Mar 9, 2018

If required, we could easily implement a new method unfold for the case that we actually want to unfold the AST. This would also make the memory/time implications clear. However, it seems not to be needed at the moment.

@merkste merkste force-pushed the DAG-aware-copying branch from acb294c to ef39b93 Compare March 9, 2018 12:46
@merkste merkste force-pushed the DAG-aware-copying branch 2 times, most recently from 9255921 to 4008148 Compare March 9, 2018 17:17
After certain replacements, e.g., formula substitution, the AST becomes a directed acyclic graph.
Most often it is not required to visit a node of this DAG multiply times.
The new class DAGVisitor keeps track of the nodes already seen and visits each node only once.

The class DAGVisitor is inserted between ASTVisitor and ASTTraverse and ASTTraverseModify
without changing the behavior of their subclasses.
@merkste merkste force-pushed the DAG-aware-copying branch 2 times, most recently from 94eb434 to 3b35763 Compare March 12, 2018 18:13
@merkste
Copy link
Contributor Author

merkste commented Mar 12, 2018

I've rearranged and split some commits to make the PR more approachable.

@merkste merkste force-pushed the DAG-aware-copying branch from 3b35763 to 6e4ea8c Compare March 12, 2018 18:22
Rename the method visit to visitNow in existing visitor classes.
This makes them traverse the AST without visiting nodes multiple times.
@merkste merkste force-pushed the DAG-aware-copying branch from 6e4ea8c to 944aff4 Compare March 12, 2018 20:29
Steffen Märcker added 2 commits April 24, 2018 17:27
Implement Object#clone to support shallow copies of ASTElements.
Overrides should take care to also clone inner container types, such as lists and vectors.
After certain replacements, e.g., formula substitution, the AST becomes a directed acyclic graph.
On copying wewant to preserve this structure.
The identification of duplicates is non-local since duplicates may appear everywhere in the AST/DAG.

The implementation introduces a new visitor to keep track of duplicate nodes
and makes copying a two-step process:
1. Cloning a node and its internal container types via Object::clone
2. Deep-copying AST child nodes using the visitor
@merkste merkste force-pushed the DAG-aware-copying branch from 9f2eb9d to 1f5d7ed Compare May 8, 2019 08:22
@davexparker davexparker added the WIP Work in progress/under discussion, not ready for merge label Sep 10, 2021
@davexparker davexparker force-pushed the master branch 2 times, most recently from ca12ca0 to 6bf73df Compare January 12, 2024 14:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

WIP Work in progress/under discussion, not ready for merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants