77import liquidjava .rj_language .Predicate ;
88import liquidjava .rj_language .ast .BinaryExpression ;
99import liquidjava .rj_language .ast .Expression ;
10+ import liquidjava .rj_language .opt .VCSimplificationResult ;
1011import liquidjava .utils .Utils ;
1112import spoon .reflect .cu .SourcePosition ;
1213import spoon .reflect .reference .CtTypeReference ;
@@ -122,73 +123,47 @@ public static void smtStart(VCImplication chain, Predicate extraPremise, Predica
122123 System .out .println (SMT_TAG + " " + formatConclusion (conclusion ));
123124 }
124125
125- /**
126- * Print the simplifier input and output side by side. This keeps the raw expression visible in debug traces while
127- * callers continue using the simplified expression for user-facing diagnostics. Long predicates are split on
128- * top-level {@code &&} so each conjunct lands on its own line.
129- */
130- public static void simplification (Expression input , Expression output ) {
131- if (!enabled ()) {
132- return ;
133- }
134- printSplitConjunction ("Before simplification:" , Colors .YELLOW , input );
135- printSplitConjunction ("After simplification: " , Colors .BOLD_YELLOW , output );
136- }
137-
138- private static void printSplitConjunction (String header , String color , Expression exp ) {
139- List <Expression > conjuncts = new ArrayList <>();
140- flattenConjunction (exp , conjuncts );
141- if (conjuncts .size () <= 1 ) {
142- System .out .println (SMP_TAG + " " + header + " " + color + exp + Colors .RESET );
143- return ;
144- }
145- System .out .println (SMP_TAG + " " + header );
146- String joiner = " " + Colors .GREY + "&&" + Colors .RESET ;
147- for (int i = 0 ; i < conjuncts .size (); i ++) {
148- String suffix = (i < conjuncts .size () - 1 ) ? joiner : "" ;
149- System .out .println (SMP_TAG + " " + color + conjuncts .get (i ) + Colors .RESET + suffix );
150- }
151- }
152-
153126 private static final String PASS_NAME_COLOR = Colors .GOLD ;
154127 private static final int PASS_NAME_WIDTH = 28 ;
155128 private static int simplificationPass ;
156129 private static String previousSimplification ;
157130
158- /**
159- * Start a simplification log. DebugLog owns the running pass number and the previous expression snapshot because
160- * both are only needed for debug output.
161- */
162- public static void simplificationStart (Expression input ) {
131+ public static void simplificationStart (VCImplication input ) {
163132 if (!enabled ()) {
164133 return ;
165134 }
166- previousSimplification = input . toString ( );
135+ previousSimplification = formatSimplification ( input );
167136 simplificationPass = 0 ;
168- printSimplificationPass (simplificationPass , "initial expression " , previousSimplification );
137+ printSimplificationPass (simplificationPass , "initial VC " , previousSimplification );
169138 }
170139
171- /**
172- * One line per simplifier phase.
173- */
174- public static void simplificationPass (String name , Expression result ) {
175- if (!enabled ()) {
140+ public static void simplificationPass (VCSimplificationResult result ) {
141+ if (!enabled () || result == null || result .getSimplification () == null ) {
176142 return ;
177143 }
178- String resultStr = result .toString ();
179- printSimplificationPass (++simplificationPass , name , previousSimplification , resultStr );
144+ if (previousSimplification == null && result .getOrigin () != null ) {
145+ previousSimplification = formatSimplification (result .getOrigin ().getImplication ());
146+ }
147+ String resultStr = formatSimplification (result .getImplication ());
148+ printSimplificationPass (++simplificationPass , result .getSimplification (), previousSimplification , resultStr );
180149 previousSimplification = resultStr ;
181150 }
182151
152+ public static void simplificationEnd (VCSimplificationResult result ) {
153+ if (!enabled ()) {
154+ return ;
155+ }
156+ String finalSimplification = result == null ? "" : formatSimplification (result .getImplication ());
157+ printSimplificationPass (++simplificationPass , "Final VC" , finalSimplification );
158+ System .out .printf ("%s end: %sFixed Point%s%n" , SMP_TAG , Colors .GREY , Colors .RESET );
159+ previousSimplification = null ;
160+ simplificationPass = 0 ;
161+ }
162+
183163 /**
184- * Prints {@code (no change)} when the step left the expression unchanged, and otherwise emits a unified-diff-style
185- * pair (red {@code -} for the previous expression with removed tokens highlighted, green {@code +} for the new one
186- * with added tokens highlighted), so substitutions inside a long predicate are obvious at a glance.
187- *
188- * <p>
189- * {@code previous} is taken as a string rather than an {@link Expression} because the simplifier mutates the AST in
190- * place: caching an {@code Expression} reference and re-stringifying it after a later pass would yield the
191- * already-mutated form, masking real changes as "no change".
164+ * Prints {@code (no change)} when the step left the VC unchanged, and otherwise emits a unified-diff-style pair
165+ * (red {@code -} for the previous VC with removed tokens highlighted, green {@code +} for the new one with added
166+ * tokens highlighted), so substitutions inside a long VC are obvious at a glance.
192167 */
193168 private static void printSimplificationPass (int pass , String name , String previous , String result ) {
194169 if (previous != null && previous .equals (result )) {
@@ -198,16 +173,34 @@ private static void printSimplificationPass(int pass, String name, String previo
198173 }
199174 System .out .printf ("%s pass %02d: %s%s%s%n" , SMP_TAG , pass , PASS_NAME_COLOR , name , Colors .RESET );
200175 if (previous == null ) {
201- System . out . printf ( "%s %s%n" , SMP_TAG , result );
176+ printBlock ( result );
202177 return ;
203178 }
204179 String [] diff = wordDiff (previous , result );
205- System . out . printf ( "%s %s-%s %s%n " , SMP_TAG , Colors .RED , Colors . RESET , diff [0 ]);
206- System . out . printf ( "%s %s+%s %s%n " , SMP_TAG , Colors .GREEN , Colors . RESET , diff [1 ]);
180+ printDiffBlock ( "- " , Colors .RED , diff [0 ]);
181+ printDiffBlock ( "+ " , Colors .GREEN , diff [1 ]);
207182 }
208183
209184 private static void printSimplificationPass (int pass , String name , String result ) {
210- System .out .printf ("%s pass %02d: %s%n %s%n" , SMP_TAG , pass , paintPassName (name ), result );
185+ System .out .printf ("%s pass %02d: %s%n" , SMP_TAG , pass , paintPassName (name ));
186+ printBlock (result );
187+ }
188+
189+ private static String formatSimplification (VCImplication implication ) {
190+ return implication == null ? "" : implication .toString ().stripTrailing ();
191+ }
192+
193+ private static void printBlock (String text ) {
194+ for (String line : text .split ("\\ R" , -1 )) {
195+ System .out .printf ("%s %s%n" , SMP_TAG , line );
196+ }
197+ }
198+
199+ private static void printDiffBlock (String marker , String color , String text ) {
200+ String prefix = color + marker + Colors .RESET ;
201+ for (String line : text .split ("\\ R" , -1 )) {
202+ System .out .printf ("%s %s %s%n" , SMP_TAG , prefix , line );
203+ }
211204 }
212205
213206 /**
@@ -223,7 +216,7 @@ private static String paintPassName(String name) {
223216 /**
224217 * Word-level LCS diff. Returns {@code [previousColored, currentColored]} where tokens that don't appear in the LCS
225218 * are wrapped in red (for the previous string) and green (for the current string). Splitting on a single space is
226- * intentional — the {@link Expression#toString()} output spaces operators and operands.
219+ * intentional because VC and expression formatting space operators and operands.
227220 */
228221 private static String [] wordDiff (String previous , String current ) {
229222 String [] prev = previous .split (" " );
0 commit comments