/* // old modified one -- behaves the same as the new one but slower.
class sc_pair
{
    tuple tuple;
    pa partial;
    
    public String toString()
    {
        return tuple+";"+partial;
    }
}

final class supports_current_backtrack
{
    ArrayList<ArrayList<sc_pair>> pairs;
    ArrayList<TIntArrayList> removal; // 1 if it was a removal; 0 otherwise
    
    // These map tree depth to the actions that happened at that tree depth.
    // These actions obviously need to be undone in sequence.
    
    int level;                // Current tree depth 0.. #vars
    gac_schema constraint;
    
    supports_current_backtrack(gac_schema cons)
    {
        constraint=cons;
        
        pairs= new ArrayList<ArrayList<sc_pair>>(10000);
        removal= new ArrayList<TIntArrayList>(10000);
        // init backtrack stack.
        level=-1;
    }
    
    final void add_backtrack_level()
    {
        level++;
        removal.add(new TIntArrayList());
        pairs.add(new ArrayList<sc_pair>());
    }
    
    final void add_addition(pa partial, tuple tau)
    {
        sc_pair temp=new sc_pair();
        temp.partial=partial;
        temp.tuple=tau;
        pairs.get(level).add(temp);
        removal.get(level).add(0);
    }
    
    final void add_removal(pa partial, tuple tau)
    {
        sc_pair temp=new sc_pair();
        temp.partial=partial;
        temp.tuple=tau;
        pairs.get(level).add(temp);
        removal.get(level).add(1);
    }
    
    final void backtrack()
    {   // backtrack one level.
        // By sheer fluke this works correctly when a tuple is added then removed. The removal is 
        // backtracked first, then the addition.
        ArrayList<sc_pair> p=pairs.get(level);
        TIntArrayList r=removal.get(level);
        
        for(int index=p.size()-1; index>=0; index--)
        {
            if(r.get(index)==0)
            {
                // it was an addition so remove it.
                ((linktuple)constraint.supports_current.get(p.get(index).partial)).remove(p.get(index).tuple);
            }
            else
            {
                // put the value back
                ((linktuple)constraint.supports_current.get(p.get(index).partial)).insert_end(p.get(index).tuple);
            }
        }
        
        // delete so that the next call to add does add in the correct place
        pairs.remove(level);
        removal.remove(level);
        
        level--;
    }
}*/

/* // old old one -- this behaves slightly different to the new one so I think it has a bug.
class sc_pair
{
    tuple tuple;
    pa partial;
    
    public String toString()
    {
        return tuple+";"+partial;
    }
}

final class supports_current_backtrack
{
    ArrayList<ArrayList<sc_pair>> removals;
    ArrayList<ArrayList<sc_pair>> additions;
    
    // These map tree depth to the actions that happened at that tree depth.
    // These actions obviously need to be undone in sequence.
    
    int level;                // Current tree depth 0.. #vars
    gac_schema constraint;
    
    supports_current_backtrack(gac_schema cons)
    {
        constraint=cons;
        removals= new ArrayList<ArrayList<sc_pair>>(10000);
        additions= new ArrayList<ArrayList<sc_pair>>(10000);
        
        // init backtrack stack.
        level=-1;
    }
    
    final void add_backtrack_level()
    {
        level++;
        removals.add(new ArrayList<sc_pair>());
        additions.add(new ArrayList<sc_pair>());
    }
    
    final void add_addition(pa partial, tuple tau)
    {
        sc_pair temp=new sc_pair();
        temp.partial=partial;
        temp.tuple=tau;
        additions.get(level).add(temp);
    }
    
    final void add_removal(pa partial, tuple tau)
    {
        sc_pair temp=new sc_pair();
        temp.partial=partial;
        temp.tuple=tau;
        removals.get(level).add(temp);
    }
    
    final void backtrack()
    {   // backtrack one level.
        // By sheer fluke this works correctly when a tuple is added then removed. The removal is 
        // backtracked first, then the addition.
        
        for(sc_pair pair : removals.get(level))
        {
            // put the value back
            ((linktuple)constraint.supports_current.get(pair.partial)).insert_end(pair.tuple);
        }
        
        for(sc_pair pair : additions.get(level))
        {
            // remove the value
            ((linktuple)constraint.supports_current.get(pair.partial)).remove(pair.tuple);
        }
        
        // delete so that the next call to add does add in the correct place
        additions.remove(level);
        removals.remove(level);
        
        level--;
    }
}*/

/*
// old version. on noughts3, this causes DWO to occur for a different variable in two places. Same tree. Could be bugged
// or perhaps new version is bugged.
class ls_pair
{
    pa partial;
    tuple oldtuple;
}

final class last_support_backtrack
{
    // last_support maps a partial to a tuple.
    ArrayList<ArrayList<ls_pair>> actions;
    
    // These map tree depth to the actions that happened at that tree depth.
    // These actions obviously need to be undone in reverse sequence.
    
    int level;                // Current tree depth 0.. #vars
    gac_schema constraint;
    
    last_support_backtrack(gac_schema cons)
    {
        constraint=cons;
        actions= new ArrayList<ArrayList<ls_pair>>(10000);
        
        // init backtrack stack.
        level=-1;
    }
    
    final void add_backtrack_level()
    {
        level++;
        actions.add(new ArrayList<ls_pair>());
    }
    
    final void add_action(pa partial, tuple oldtuple)
    {
        ls_pair temp=new ls_pair();
        temp.partial=partial;
        temp.oldtuple=oldtuple;
        actions.get(level).add(temp);
    }
    
    final void backtrack()
    {   // backtrack one level.
        
        ArrayList<ls_pair> changes=actions.get(level);
        
        for(int counter=changes.size()-1; counter>=0; counter--)
        {
            ls_pair pair=changes.get(counter);
            
            // put the value back. If the map had no mapping before, now it has a mapping to null.
            // Check that this is OK.
            constraint.last_support.put(pair.partial, pair.oldtuple);
        }
        
        // delete so that the next call to add does add in the correct place
        actions.remove(level);
        
        level--;
    }
}*/


