Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

138
LINES

< > BotCompany Repo | #1035398 // BStack_v3 - a virtual stack with backtracking capability (version 3, copying the stack even more lazily, dev.)

JavaX fragment (include) [tags: use-pretranspiled]

Libraryless. Click here for Pure Java version (22976L/140K).

1  
// This backtracking-enabled stack (BStack) postpones cloning stack
2  
// frames as long as possible.
3  
// More specifically, only the current top frame is actually mutable.
4  
// Some stack frames below (from 0 up to clonePointer) may not be
5  
// cloned yet, and are cloned (=made mutable) by the pop() function.
6  
7  
// The tests (test_BStack_v3) pass, but they might not test the lazy
8  
// cloning. So for safety, stick with BStack_v2 until there are more
9  
// tests for BStack_v3.
10  
11  
// A represents the return type of the backtrackable main computation
12  
sclass BStack_v3<A> extends VStack is IBStack<A> {
13  
  static int idCounter;
14  
  int stackID = ++idCounter; // for debugging
15  
  
16  
  // elements at this index and below must be cloned before use
17  
  int clonePointer = -1;
18  
  
19  
  // cloned version made at last branch point
20  
  selfType snapshot;
21  
  
22  
  // remaining options at last branch point
23  
  Iterator<IVF1> options;
24  
  
25  
  // steps to undo before switching to the alternative
26  
  L<AutoCloseable> undos;
27  
  
28  
  *() {}
29  
  *(Computable<A> computation) { push(computation); }
30  
  *(Iterable<Computable> l) { pushAll(l); }
31  
  
32  
  selfType cloneStack() {
33  
    new selfType s;
34  
    s.snapshot = snapshot;
35  
    s.options = options;
36  
    s.undos = undos;
37  
    undos = null;
38  
    s.stack = cloneList(stack);
39  
    
40  
    // Directly clone current function, clone older stack entries
41  
    // lazily.
42  
    
43  
    replaceLast(s.stack, shallowClone(last(stack)));
44  
    clonePointer = l(stack)-2;
45  
    ret s;
46  
  }
47  
  
48  
  public void addUndo(AutoCloseable undo) {
49  
    if (undo == null || snapshot == null) ret;
50  
    if (undos == null) undos = new L;
51  
    undos.add(undo);
52  
  }
53  
  
54  
  public <B extends VStack.Computable> void options(B function, IVF1<B>... options) {
55  
    options(function, arrayIterator(options));
56  
  }
57  
    
58  
  public <B extends VStack.Computable> void options(B function, Iterable<IVF1<B>> options) {
59  
    Iterator<IVF1<B>> iterator = nonNullIterator(iterator(options));
60  
    
61  
    if (!iterator.hasNext())
62  
      throw new NoOptionsException;
63  
      
64  
    IVF1<B> firstOption = iterator.next();
65  
    
66  
    // All options except first are stored as alternatives
67  
    // in cloned stacks.
68  
    
69  
    setOptions(iterator);
70  
71  
    // Execute the first option
72  
    firstOption.get(function);
73  
  }
74  
  
75  
  <B> void setOptions(Iterator<IVF1<B>> options) {
76  
    snapshot = cloneStack();
77  
    this.options = (Iterator) options;
78  
  }
79  
  
80  
  // Try to backtrack one step and return a new stack
81  
  // Returns null if no backtracking possible
82  
  public selfType backtrack() ctex {
83  
    // Apply undos in reverse order
84  
    for (int i = l(undos)-1; i >= 0; i--)
85  
      undos.get(i).close();
86  
        
87  
    // no more options? done
88  
    if (options == null || !options.hasNext()) null;
89  
    
90  
    // get snapshot and option to execute
91  
    selfType nextStack = snapshot;
92  
    var option = options.next();
93  
    
94  
    // If there are more options in the list, make another clone
95  
    // of the snapshot
96  
    bool moreOptions = options.hasNext();
97  
    if (moreOptions) {
98  
      nextStack = new selfType;
99  
      nextStack.stack = shallowCloneElements(snapshot.stack);
100  
      nextStack.snapshot = snapshot;
101  
      nextStack.options = options;
102  
    }
103  
    
104  
    nextStack.push(new ExecuteOption(option));
105  
    ret nextStack;
106  
  }
107  
  
108  
  public A nextResult() {
109  
    stepAll(this);
110  
    return (A) latestResult;
111  
  }
112  
  
113  
  // calculate next result and print stack at every step
114  
  public A nextResultWithPrintStruct(long maxSteps) {
115  
    stepMaxWithPrintIndentedStruct(this, maxSteps);
116  
    return (A) latestResult;
117  
  }
118  
  
119  
  protected void pop :: after {
120  
    int idx = l(stack)-1;
121  
    
122  
    // Clone the new top stack frame if necessary
123  
    if (idx >= 0 && idx == clonePointer) {
124  
      stack.set(idx, shallowClone(stack.get(idx)));
125  
      --clonePointer;
126  
    }
127  
  }
128  
  
129  
  srecord noeq ExecuteOption(IVF1 option) is VStack.Computable {
130  
    public void step(VStack stack, O subComputationResult) {
131  
      O target = stack.caller();
132  
      stack.return();
133  
      option.get(target);
134  
    }
135  
  }
136  
  
137  
  sclass NoOptionsException extends RuntimeException {}
138  
}

Author comment

Began life as a copy of #1035394

download  show line numbers  debug dex  old transpilations   

Travelled to 3 computer(s): ekrmjmnbrukm, mowyntqkapby, mqqgnosmbjvj

No comments. add comment

Snippet ID: #1035398
Snippet name: BStack_v3 - a virtual stack with backtracking capability (version 3, copying the stack even more lazily, dev.)
Eternal ID of this version: #1035398/11
Text MD5: f95e85c1f74d162b000c79f3ed66309c
Transpilation MD5: ce82fffbbbcf338165d8694fca012a5e
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-05-06 23:25:22
Source code size: 4145 bytes / 138 lines
Pitched / IR pitched: No / No
Views / Downloads: 131 / 229
Version history: 10 change(s)
Referenced in: [show references]