Update `docs/fir/pcla.md` to make things more clear

After reading the document I left with some questions unanswered. This
commit addresses them.

`refineSubstitutedMemberIfReceiverContainsTypeVariable` doesn't exist
and `updateSubstitutedMemberIfReceiverContainsTypeVariable` is the only
member in `FirCallCompletionResultsWriterTransformer` that uses the API
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/candidate/Candidate.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/candidate/Candidate.kt
index fad4050..8776990 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/candidate/Candidate.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/candidate/Candidate.kt
@@ -327,7 +327,7 @@
     /**
      * Please avoid updating symbol in the candidate whenever it's possible.
      * The only case when currently it seems to be unavoidable is at
-     * [org.jetbrains.kotlin.fir.resolve.transformers.FirCallCompletionResultsWriterTransformer.refineSubstitutedMemberIfReceiverContainsTypeVariable]
+     * [org.jetbrains.kotlin.fir.resolve.transformers.FirCallCompletionResultsWriterTransformer.updateSubstitutedMemberIfReceiverContainsTypeVariable]
      */
     @RequiresOptIn
     annotation class UpdatingCandidateInvariants
diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt
index cc27169..6477122 100644
--- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt
+++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt
@@ -203,7 +203,7 @@
     }
 
     /**
-     * General documentation for builder inference algorithm is located at `/docs/fir/builder_inference.md`
+     * General documentation for PCLA algorithm is located at `/docs/fir/pcla.md`
      *
      * This function checks if any of the postponed arguments are suitable for builder inference, and performs it for all eligible lambda arguments
      * @return true if we got new proper constraints after builder inference
diff --git a/docs/fir/pcla.md b/docs/fir/pcla.md
index 26332ac..d87f2ea 100644
--- a/docs/fir/pcla.md
+++ b/docs/fir/pcla.md
@@ -12,7 +12,7 @@
 fun <E> buildList(builderAction: MutableList<E>.() -> Unit): List<E> = ...
 
 fun main() {
-    buildList { 
+    buildList {
         add("")
     } // E is inferred to `String`
 }
@@ -33,19 +33,28 @@
 
 PCLA is the way of lambda analysis during call completion that happens when some input types are not properly inferred, and there are no other sources of constraints.
 
-**PCLA lambda** = lambda analyzed with PCLA
+> Please note that PCLA analysis runs during call completion, which in turn only happens when the overload resolution has successfully ended with the single candidate result (When no `OVERLOAD_RESOLUTION_AMBIGUITY` is reported)
 
-**Main call/candidate** is the call that contains PCLA lambda
+**PCLA lambda** is the lambda analyzed with PCLA algorithm.
 
-**Nested call/candidate** is a call being resolved in other than `ContextDependent` mode (usually statement-level) that belongs to PCLA lambda
-  * **Postponed nested calls** are nested calls which we decided not to complete in the FULL mode immediately
+**Main call/candidate** is the call that contains *PCLA lambda*.
+*Main candidate* is the only candidate left after overload resolution that corresponds to the *main call*.
 
-**Shared CS** is a constraint system being shared between postponed nested calls inside PCLA lambda
+**Nested call/candidate** is a "statement-level" call (non-`ContextDependent`-mode expressions) inside lambda.
+In the context of PCLA, we don't complete *nested calls* in the `FULL` mode immediately, but postpone them.
+We call such calls **Postponed nested calls**.
 
-**Outer CS**
-  * Defined only for nested postponed candidates (for shared CS)
-  * It consists of type variables of the containing PCLA lambdas and all the type variables of already processed inner candidates
-  * For inner CS, all the outer CS-related type variables are always coming at the beginning of the list of all variables
+**Shared CS** is the constraint system being shared between postponed *nested calls* inside *PCLA lambda*.
+
+**Outer/Inner CS** is another, perpendicular way to classify constraint systems.
+Or it's rather an implementation mechanism.
+Outer CS is the "original CS", while "inner CS" is the CS that built on top of the outer CS.
+Inner CS has access to all outer CS type variables and constraints.
+In the context of PCLA, we use "inner CS" mechanism to analyze *nested calls*.
+*Shared CS* is implemented as *inner CS*.
+
+* *Outer CS* consists of type variables of the containing PCLA lambdas and all the type variables of already processed *nested candidates*
+* For *inner CS*, all the outer CS-related type variables are always coming at the beginning of the list of all variables
 
 **Outer Type Variable (TV)**
   * In the context of *shared CS*, it's a subset of type variables that are brought from the *outer CS*
@@ -54,8 +63,8 @@
 
 ## Entry-point to PCLA
 
-The conditions to run a lambda resolution in PCLA mode is the following:
-- Completion mode for the current call tree is `FULL` 
+The conditions to run a lambda resolution in PCLA mode are the following:
+- Completion mode for the current call tree is `FULL`
 - There are no other ways to infer some new constraints for any type variable.
 - There is some lambda that among its input types has at least one with a not fixed TV being used as type argument
     - So, if one of the input types is `MutableList<Ev>` that lambda suits for PCLA
@@ -94,13 +103,13 @@
 
 * In the end, the **root CS** (aka CS for the Main candidate) contains TVs for all incomplete nested candidates.
 * And may just continue `FULL` completion process on the Main, i.e., fixing variables for which we now have new proper constraints, 
-  and analyze other lambdas.
+  and analyze other lambdas (which might run PCLA analysis for other lambdas).
 * In the end, beside completion results writing for the main call, we also write results (inferred type arguments/expression type update) 
   for all incomplete/postponed calls (see `FirCallCompletionResultsWriterTransformer.runPCLARelatedTasksForCandidate`).
 
 ### Example 1
 
-```
+```kotlin
 fun foo() {}
 
 fun main() {
@@ -119,11 +128,11 @@
         // And constraints
         // String <: Tv [from List<String> <: Iterable<Tv>]
         // MutableList<Ev> <: Cv
-        // Rv <: Ev [incorporation from MutableList<Ev> <: MutableCollection<in Rv> 
+        // Rv <: Ev [incorporation from MutableList<Ev> <: MutableCollection<in Rv>]
         // Fixing Tv := String
         // Starting lamda analysis
         // Having 
-        // Rv <: String constraint
+        // String <: Rv constraint
         // 
         // Then add all the new constraints to the shared CS
         x.mapTo(this) { it } // Postponed nested call
@@ -133,14 +142,17 @@
     // Ev := String
     // Rv := String
     // Cv := MutableList<String>
+}
 ```
 
 ### Example 2
 ```kotlin
-fun <A, B, C> twoSteps(first: Inv<A>.() -> Unit, b: B, second: (B) -> C): Triple<A, B, C> {
+class Inv<A>() { fun set(a: A) = Unit }
+
+fun <A, B, C> twoSteps(first: Inv<A>.() -> Unit, b: B, second: (B) -> C): Triple<Inv<A>, B, C> {
     val a = Inv<A>().apply(first)
-    val c = second(value)
-    return Triple(a, value, c)
+    val c = second(b)
+    return Triple(a, b, c)
 }
 
 fun main() {
@@ -255,7 +267,7 @@
 And after that we finally call `processPartiallyResolvedCall` for `myOtherCallWithLambda { ... }`, but it doesn't contain constraints 
 on `Ev` from `add(""")`, thus overwriting existing information.
 
-That might be workarounded with some kind of merging constraints for the same TV instead of just replacement 
+That might be circumvented with some kind of merging constraints for the same TV instead of just replacement
 (see `NewConstraintSystemImpl.addOtherSystem`), but that seems to be hacky too.
 
 So, the current approach is the following: during nested lambda resolution we assume that currently *shared CS* is equal to the CS of the
@@ -337,7 +349,7 @@
 of lambdas. That part works the same way as for regular calls outside PCLA context.
 
 ### Example
-```
+```kotlin
 fun foo(x: List<String>) {
     buildList {
         x.mapTo(this) { // `mapTo` analyzed in PCLA_POSTPONED_CALL
@@ -426,7 +438,7 @@
 (e.g., [KT-68940](https://youtrack.jetbrains.com/issue/KT-68940/K2-IllegalArgumentException-All-variables-should-be-fixed-to-something)) 
 where the return type might contain not-fixed type variables.
 
-For **non**-PCLA lambdas using expected types with non-fixed type variables would lead to illegal state: 
+For **non**-PCLA lambdas, using expected types with non-fixed type variables would lead to illegal state:
 calls inside return statements are not aware of type variables of the containing call.
 
 But for PCLA, we resolve everything within a common CS; thus it's ok. 
@@ -455,8 +467,8 @@
 }
 ```
 
-By default, (e.g., in non-PCLA context) we would postpone the lambda in the `let` call, and after exiting PCLA for `myBuildSet` would fix `Ev`
-into the only existing constraint at that moment, i.e., to `Base1` and then when got back to the nested lambda analysis would report
+By default, (e.g., in non-PCLA context) we would postpone the lambda in the `let` call, and after exiting lambda for `myBuildSet`, we would fix `Ev`
+into the only existing constraint at that moment, i.e., to `Derived1` and then when got back to the nested lambda analysis would report
 a `TYPE_MISMATCH` in the `it.add(Derived2())` because the variable has been already fixed to less permissive type.
 
 But that looks counter-intuitive, and moreover, the example above was green in Builder Inference implementation in K1.
@@ -479,6 +491,7 @@
             }
         }
         builder.add({ x: String -> })
+        builder.first()
     }
 }
 ```
@@ -553,7 +566,7 @@
     buildList {
         // Adding the constraints
         // MutableList<String> <: Sv
-        // MutableList<Ev <: Sv
+        // MutableList<Ev> <: Sv
         // But to analyze lambda we fix Sv to CST(MutableList<String>, MutableList<Ev>) = MutableList<CST(String, Ev)>
         // The question is what is CST(String, Ev)
         selectL(x, this) { x ->