package mb.statix.solver;

import java.util.Iterator;
import java.util.Optional;
import java.util.Set;

import com.google.common.collect.Sets;

public class Solver {

    private Solver() {
    }

    public static Config solve(Config config, IDebugContext debug) throws InterruptedException {
        debug.info("Solving constraints");

        // set-up
        final Set<IConstraint> constraints = Sets.newConcurrentHashSet(config.getConstraints());
        State state = config.state();

        // fixed point
        boolean progress = true;
        outer: while(progress) {
            progress = false;
            final Iterator<IConstraint> it = constraints.iterator();
            while(it.hasNext()) {
                if(Thread.interrupted()) {
                    throw new InterruptedException();
                }
                final IConstraint constraint = it.next();
                debug.info("Solving {}", constraint.toString(state.unifier()));
                Optional<Config> maybeResult = constraint.solve(state.withErroneous(false), debug.subContext());
                if(maybeResult.isPresent()) {
                    progress = true;
                    it.remove();
                    final Config result = maybeResult.get();
                    state = result.state();
                    if(!debug.isRoot() && state.isErroneous()) {
                        debug.info("Break early because of errors.");
                        break outer;
                    }
                    // FIXME update properties in state
                    debug.info("Simplified {} to {}", constraint.toString(state.unifier()), result.getConstraints());
                    constraints.addAll(result.getConstraints());
                } else {
                    debug.info("Delayed {}", constraint.toString(state.unifier()));
                }
            }
        }

        // return
        debug.info("Solved {} errors and {} remaining constraints.", state.isErroneous() ? "with" : "without",
                constraints.size());
        return Config.of(state, constraints);
    }

}
@@ -952,32 +952,93 @@
 te.unifier()));%0A
+                IDebugContext subDebug = debug.subContext();%0A
                 
@@ -1113,34 +1113,24 @@
 false), 
-debug.subContext()
+subDebug
 );%0A     
@@ -1607,33 +1607,36 @@
                 
-d
+subD
 ebug.info(%22Simpl
@@ -1644,19 +1644,16 @@
 fied
- %7B%7D
  to %7B%7D%22,
  con
@@ -1652,46 +1652,8 @@
 %7B%7D%22,
- constraint.toString(state.unifier()),
  res
@@ -1777,33 +1777,36 @@
                 
-d
+subD
 ebug.info(%22Delay
@@ -1811,50 +1811,9 @@
 ayed
- %7B%7D%22, constraint.toString(state.unifier())
+%22
 );%0A 

Improve output further.