| dirs[ino0] = mkdir(m0, md0, # links(ino0, dirs), m3, entries0), err = ESUCCESS, ino = entries0[str], p = p2, afs-cons(dirs, files), ispath(q, ROOT_INO, ino0, dirs, files), px(user, md0), ino0 ∈ dirs, str ∈ entries0, q ≠ ε → px(user, parent(q), ROOT_INO, dirs, files), links(ino0, dirs) ≠ ∅ ∨ ino0 = ROOT_INO, ∀ p1, err, p, p_ino, ino, dirs, files, q, user, asynced. # p1 < #(str + p2) → 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))) ⊦ [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(p2, entries0[str], ino, dirs, files) ∧ px-parent(user, q + str ' + p2, ROOT_INO, dirs, files) ∨ err = ENOENT ∧ ¬ ispath(p2, entries0[str], dirs, files) ∨ err = EACCESS ∧ (∃ p'. p' ⊑ parent(str ' + p2) ∧ ispath(p', ino0, dirs, files) ∧ ¬ px(user, q + p', ROOT_INO, dirs, files))) |
dirs[ino0] = mkdir(m0, md0, # links(ino0, dirs), m3, entries0), err = ESUCCESS, ino = entries0[str], p = p2, afs-cons(dirs, files), ispath(q, ROOT_INO, ino0, dirs, files), px(user, md0), str ∈ entries0, ino0 ∈ dirs, q ≠ ε → px(user, parent(q), ROOT_INO, dirs, files), links(ino0, dirs) ≠ ∅ ∨ ino0 = ROOT_INO, ∀ p1, err, p, p_ino, ino, dirs, files, q, user, asynced. # p1 < #(str + p2) → 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))) ⊦ [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(p2, entries0[str], ino, dirs, files) ∧ px-parent(user, q + str ' + p2, ROOT_INO, dirs, files) ∨ err = ENOENT ∧ ¬ ispath(p2, entries0[str], dirs, files) ∨ err = EACCESS ∧ (∃ p'. p' ⊑ parent(str ' + p2) ∧ ispath(p', ino0, dirs, files) ∧ ¬ px(user, q + p', ROOT_INO, dirs, files))), err = ESUCCESS ∧ p = p2 ∧ entries0[str] = ino ∧ afs-cons(dirs, files) ∧ ispath(q + str, ROOT_INO, ino, dirs, files) ∧ ino ∈ dirs ∧ (q + str ≠ ε → px(user, parent(q + str), 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(p2, entries0[str], ino, dirs, files) ∧ px-parent(user, (q + str) + p2, ROOT_INO, dirs, files) ∨ err = ENOENT ∧ ¬ ispath(p2, entries0[str], dirs, files) ∨ err = EACCESS ∧ p2 ≠ ε ∧ (∃ p'. p' ⊑ parent(p2) ∧ ispath(p', entries0[str], dirs, files) ∧ ¬ px(user, (q + str) + p', ROOT_INO, dirs, files))), dirs[ino0] = mkdir(m0, md0, # links(ino0, dirs), m3, entries0), err = ESUCCESS, ino = entries0[str], p = p2, afs-cons(dirs, files), ispath(q, ROOT_INO, ino0, dirs, files), px(user, md0), str ∈ entries0, ino0 ∈ dirs, q ≠ ε → px(user, parent(q), ROOT_INO, dirs, files), links(ino0, dirs) ≠ ∅ ∨ ino0 = ROOT_INO, ∀ p1, err, p, p_ino, ino, dirs, files, q, user, asynced. # p1 < #(str + p2) → 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))) ⊦ [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(p2, entries0[str], ino, dirs, files) ∧ px-parent(user, q + str ' + p2, ROOT_INO, dirs, files) ∨ err = ENOENT ∧ ¬ ispath(p2, entries0[str], dirs, files) ∨ err = EACCESS ∧ (∃ p'. p' ⊑ parent(str ' + p2) ∧ ispath(p', ino0, dirs, files) ∧ ¬ px(user, q + p', ROOT_INO, dirs, files)))
Used simplifier rules: ⊦ str + p = str ' + p; (s)% ⊦ #(str ' + p) = (# p)+1; (s)% ⊦ m +1 = m + 1; (s)%a: ⊦ (p + p0) + p1 = p + p0 + p1; from specification list[path]% ⊦ m < n + 1 ↔ ¬ n < m; (s)% ⊦ ¬ n < n; (s)%a: ⊦ (m + n0) + n1 = m + n0 + n1; from specification nat-basic%c: ⊦ m + n = n + m; from specification nat-basic Used terms: p2, err, p, entries0[str], ino, dirs, files, q + str, user, asynced