Skip to content

Commit 6259300

Browse files
authored
Merge pull request #1080 from davidlatwe/patch-1
Update SOLVER.md
2 parents cf43be8 + b9b1365 commit 6259300

File tree

1 file changed

+72
-72
lines changed

1 file changed

+72
-72
lines changed

src/rez/SOLVER.md

Lines changed: 72 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -55,95 +55,95 @@ stack - if the stack is then empty, then there is no solution.
5555

5656
The pseudocode for a solve looks like this (and yes, you will have to read the
5757
solver code for full appreciation of what's going on here):
58+
```python
59+
def solve(requests):
60+
phase = create_initial_phase(requests)
61+
phase_stack = stack()
62+
phase_stack.push(phase)
63+
64+
while not solved():
65+
phase = phase_stack.pop()
66+
67+
if phase.failed:
68+
phase = phase_stack.pop() # discard previous failed phase
69+
70+
if phase.exhausted:
71+
phase, next_phase = phase.split()
72+
phase_stack.push(next_phase)
73+
74+
new_phase = solve_phase(phase)
75+
76+
if new_phase.failed:
77+
phase_stack.push(new_phase) # we keep last fail on the stack
78+
elif new_phase.solved:
79+
# some housekeeping here, like checking for cycles
80+
final_phase = finalise_phase(new_phase)
81+
phase_stack.push(final_phase)
82+
else:
83+
phase_stack.push(new_phase) # phase is exhausted
84+
85+
def solve_phase(phase):
86+
while True:
87+
changed_scopes = []
88+
added_scopes = []
89+
widened_scopes = []
5890

59-
def solve(requests):
60-
phase = create_initial_phase(requests)
61-
phase_stack = stack()
62-
phase_stack.push(phase)
63-
64-
while not solved():
65-
phase = phase_stack.pop()
66-
67-
if phase.failed:
68-
phase = phase_stack.pop() # discard previous failed phase
69-
70-
if phase.exhausted:
71-
phase, next_phase = phase.split()
72-
phase_stack.push(next_phase)
73-
74-
new_phase = solve_phase(phase)
75-
76-
if new_phase.failed:
77-
phase_stack.push(new_phase) # we keep last fail on the stack
78-
elif new_phase.solved:
79-
# some housekeeping here, like checking for cycles
80-
final_phase = finalise_phase(new_phase)
81-
phase_stack.push(final_phase)
82-
else:
83-
phase_stack.push(new_phase) # phase is exhausted
84-
85-
def solve_phase(phase):
8691
while True:
87-
changed_scopes = []
88-
added_scopes = []
89-
widened_scopes = []
92+
extractions = []
9093

91-
while True:
92-
extractions = []
94+
foreach phase.scope as scope:
95+
extractions |= collect_extractions(scope)
9396

94-
foreach phase.scope as scope:
95-
extractions |= collect_extractions(scope)
97+
if not extractions:
98+
break
99+
100+
merge(extractions)
101+
if in_conflict(extractions):
102+
set_fail()
103+
return
96104

97-
if not extractions:
98-
break
105+
foreach phase.scope as scope:
106+
intersect(scope, extractions)
99107

100-
merge(extractions)
101-
if in_conflict(extractions):
108+
if failed(scope):
102109
set_fail()
103110
return
104111

105-
foreach phase.scope as scope:
106-
intersect(scope, extractions)
107-
108-
if failed(scope):
109-
set_fail()
110-
return
111-
112-
if was_intersected(scope):
113-
changed_scopes.add(scope)
114-
115-
if was_widened(scope):
116-
widened_scopes.add(scope)
112+
if was_intersected(scope):
113+
changed_scopes.add(scope)
117114

118-
# get those extractions involving new packages
119-
new_extractions = get_new_extractions(extractions)
115+
if was_widened(scope):
116+
widened_scopes.add(scope)
120117

121-
# add them as new scopes
122-
foreach request in new_extractions:
123-
scope = new_scope(request)
124-
added_scopes.add(scope)
125-
phase.add(scope)
118+
# get those extractions involving new packages
119+
new_extractions = get_new_extractions(extractions)
126120

127-
if no (changed_scopes or added_scopes or widened_scopes):
128-
break
121+
# add them as new scopes
122+
foreach request in new_extractions:
123+
scope = new_scope(request)
124+
added_scopes.add(scope)
125+
phase.add(scope)
129126

130-
pending_reductions = convert_to_reduction_set(
131-
changed_scopes, added_scopes, widened_scopes)
127+
if not (changed_scopes or added_scopes or widened_scopes):
128+
break
132129

133-
while pending_reductions:
134-
scope_a, scope_b = pending_reductions.pop()
135-
scope_a.reduce_by(scope_b)
130+
pending_reductions = convert_to_reduction_set(
131+
changed_scopes, added_scopes, widened_scopes)
136132

137-
if totally_reduced(scope_a):
138-
set_fail()
139-
return
133+
while pending_reductions:
134+
scope_a, scope_b = pending_reductions.pop()
135+
scope_a.reduce_by(scope_b)
140136

141-
# scope_a changed so other scopes need to reduce against it again
142-
if was_reduced(scope_a):
143-
foreach phase.scope as scope:
144-
if scope is not scope_a:
145-
pending_reductions.add(scope, scope_a)
137+
if totally_reduced(scope_a):
138+
set_fail()
139+
return
146140

141+
# scope_a changed so other scopes need to reduce against it again
142+
if was_reduced(scope_a):
143+
foreach phase.scope as scope:
144+
if scope is not scope_a:
145+
pending_reductions.add(scope, scope_a)
146+
```
147147
There are 2 notable points missing from the pseudocode, related to optimisations:
148148

149149
* Scopes keep a set of package families so that they can quickly skip unnecessary

0 commit comments

Comments
 (0)