Returns the representative of this variable's equivalence class. * Note: the 'parent' pointers of some variables within this equivalence class may be adjusted (to point more directly to the * representative). * * Precondition: NULL != alpha * * Postcondition: NULL == result_value->parent */
| 23 | * Postcondition: NULL == result_value->parent |
| 24 | */ |
| 25 | static unification_var* findRoot(unification_var* alpha) { |
| 26 | /* During unification, when '.rank' fields are active, the value of 'alpha->rank' strictly increases during this loop. |
| 27 | * If 'alpha->rank' = 'i', then there must be at least 2^'i' unification variables referencing (indirectly) 'alpha'. |
| 28 | * Therefore, this loop terminates in at most log_2('n')/2 steps where 'n' is the number of unification variables in 'alpha's |
| 29 | * equivalence class. |
| 30 | * This bound holds even during freezing when 'alpha->rank' may not be activated. |
| 31 | * |
| 32 | * Note: the total number of unification variables created for type inference is linearly bounded by the number of nodes |
| 33 | * in the Simplicity expression being inferred's DAG. |
| 34 | * |
| 35 | * According to ``Worst-Case Analysis of Set Union Algorithms'' by Robert E. Tarjan and Jan van Leeuwen (1984) |
| 36 | * the "path halving" method used in this implementation is adequate to ensure that the amortized time complexity is |
| 37 | * O(InvAck('n')) and ``for all practical purposes InvAck('n') a constant no larger than four''. |
| 38 | */ |
| 39 | while (alpha->parent != NULL) { |
| 40 | if (alpha->parent->parent != NULL) alpha->parent = alpha->parent->parent; |
| 41 | alpha = alpha->parent; |
| 42 | } |
| 43 | return alpha; |
| 44 | } |
| 45 | |
| 46 | /* Begin attempt to add a new binding, 'bound', to a unification variable 'alpha' representing its equivalence class. |
| 47 | * If 'alpha' is a free variable, it becomes a bound to a copy of 'bound' and 'true' is returned. |
no outgoing calls
no test coverage detected