| err = ESUCCESS, p = p0, p_ino = ino, afs-cons(dirs, files), ispath(q, ROOT_INO, ino, dirs, files), ino ∈ dirs, q ≠ ε → px(user, parent(q), ROOT_INO, dirs, files), ∀ p1, err, p, p_ino, ino, dirs, files, q, user, asynced. # p1 < # p0 → err = ESUCCESS ∧ p = p1 ∧ p_ino = ino ∧ afs-cons(dirs, files) ∧ ispath(q, ROOT_INO, ino, dirs, files) ∧ ino ∈ dirs ∧ (q ≠ ε → px(user, parent(q), ROOT_INO, dirs, files)) → [while p ≠ ε ∧ err = ESUCCESS do {choose inode with true in vfs_may_lookup#(ino, user, dirs, files, asynced; inode, err); if err = ESUCCESS then let dent = negdentry(p.head) in {afs_lookup#(ino, dirs, files, asynced; dent, err); if err = ESUCCESS then {ino := dent.ino; p := p.tail}}}] ( ⌊err⌋ ∨ err = ESUCCESS ∧ ispath(p1, p_ino, ino, dirs, files) ∧ px-parent(user, q + p1, ROOT_INO, dirs, files) ∨ err = ENOENT ∧ ¬ ispath(p1, p_ino, dirs, files) ∨ err = EACCESS ∧ p1 ≠ ε ∧ (∃ p'. p' ⊑ parent(p1) ∧ ispath(p', p_ino, dirs, files) ∧ ¬ px(user, q + p', ROOT_INO, dirs, files))) ⊦ ⌊err⌋ , err = ESUCCESS ∧ ispath(p0, p_ino, ino, dirs, files) ∧ px-parent(user, q + p0, ROOT_INO, dirs, files), err = ENOENT ∧ ¬ ispath(p0, p_ino, dirs, files), err = EACCESS ∧ p0 ≠ ε ∧ (∃ p'. p' ⊑ parent(p0) ∧ ispath(p', p_ino, dirs, files) ∧ ¬ px(user, q + p', ROOT_INO, dirs, files)), p ≠ ε ∧ err = ESUCCESS |
Used simplifier rules: ⊦ p ≠ ε → ( px-parent(user, p, ino, dirs, files) ↔ px(user, parent(p), ino, dirs, files)); (s)% ⊦ px-parent(user, ε, ino, dirs, files); (s)%a: ⊦ (p + p0) + p1 = p + p0 + p1; from specification list[path]% ⊦ p + ε = p; (s)% ⊦ valid-ino(ino, dirs, files) ↔ ino ∈ dirs ∨ ino ∈ files; (s)% ⊦ ispath(ε, n, m, dirs, files) ↔ valid-ino(n, dirs, files) ∧ m = n; (s)% ⊦ ESUCCESS ≠ ENOENT; (s)% ⊦ ESUCCESS ≠ EACCESS; (s)% ⊦ ¬ ⌊ESUCCESS⌋ ; (s)