All Downloads are FREE. Search and download functionalities are using the official Maven repository.

models.examples.case_studies.sync.als Maven / Gradle / Ivy

module examples/case_studies/sync

/*
 * Model of a generic file synchronizer.
 *
 * Adapted from:
 *   Reference: S. Balasubramaniam and Benjamin C. Pierce,
 *   "What is a File Synchronizer", Indiana University CSCI
 *   Technical Report #507, April 22, 1998
 *
 * For a detailed description, see:
 *   http://sdg.lcs.mit.edu/pubs/theses/tnolte_masters.pdf
 *
 * author: Tina Nolte
 */

private open util/graph[Name] as graph

/**
 * The Name atom represents the hierarchy of all name sequences
 * used in the model. A Name atom represents the name, and the path
 * in the sequence of names to the root excluding the RootName.
 */
sig Name {
  children: set Name
}

fact { graph/tree[children] }

one sig RootName extends Name { }

fact { Name in RootName.*children }

// We assume that the empty path always

sig FileContents { }
one sig Dir extends FileContents { }

pred IsValidFS[fs: Name -> lone FileContents] {
   all n: Name - RootName | {
      // files don't have children
      n.fs != Dir => no (n.^children).fs
      // if a path maps to something non-nil, all prefixes do also
      some n.fs => some (n.~children).fs
   }
   // the root of a file system must be a directory
   RootName.fs = Dir
}

pred IsValidDirty[dirty: set Name] {
  all n: dirty | n.~children in dirty
  RootName in dirty => some dirty - RootName
}

pred DirtiesValid[A, B: Name -> lone FileContents, Adirty, Bdirty: set Name] {
  some O: Name -> lone FileContents | {
    IsValidFS[O]
    { n: Name | n.O != n.A } in Adirty
    { n: Name | n.O != n.B } in Bdirty
  }
}

fun RestrictFS[fs: Name -> lone FileContents, p: Name]: Name -> lone FileContents {
   fs & (p.*children -> FileContents)
}

fun RestrictFSComplement[fs: Name -> lone FileContents, p: Name]: Name -> lone FileContents {
   fs & ((Name - p.*children) -> FileContents)
}

/**
 * The following function test whether a particular synchronizer
 * operation satisfies the "reasonableness" conditions.
 * The arguments are:
 * O - the original filesystem.
 * A,B - separately modified copies
 * Adirty, Bdirty - sets of paths modified in A and B, respectively, from O.
 *
 * A',B' - results of synchronizer operation
 */
pred SyncSpec[A, B, A', B': Name -> lone FileContents, Adirty, Bdirty: set Name] {
  {
     IsValidFS[A]
     IsValidFS[B]
     IsValidDirty[Adirty]
     IsValidDirty[Bdirty]
   } => {
    {
     all p: Name | IsRelevantPath[p, A, B] => {
        SyncSpecForPath[p, A, B, A', B', Adirty, Bdirty]
     }
    }
    IsValidFS[A']
    IsValidFS[B']
   }
}

pred SyncSpecForPath[p: Name, A, B, A', B': Name -> lone FileContents, Adirty, Bdirty: set Name] {
      (p.A = p.B  =>  (p.A' = p.A && p.B' = p.B))
      (p !in Adirty => (RestrictFS[A', p] = RestrictFS[B, p] && RestrictFS[B', p] = RestrictFS[B, p]))
      (p !in Bdirty => (RestrictFS[B', p] = RestrictFS[A, p] && RestrictFS[A', p] = RestrictFS[A, p]))
      ((p in Adirty && p in Bdirty && p.A != p.B) => (RestrictFS[A',p] = RestrictFS[A,p] && RestrictFS[B',p] = RestrictFS[B,p]))
}

pred IsRelevantPath[p: Name, A, B: Name -> lone FileContents] {
   p = RootName || {
     (p.~children).A = Dir
     (p.~children).B = Dir
   }
}

pred SyncSpecExample[A, B, A', B': Name -> lone FileContents, Adirty, Bdirty: set Name] {
   IsValidFS[A]
   IsValidFS[B]
   IsValidDirty[Adirty]
   IsValidDirty[Bdirty]
   SyncSpec[A, B, A', B', Adirty, Bdirty]
   A != A'
}

//run SyncSpecExample for 3

pred SyncSpecNotUnique  {
  some A, B, A1', B1', A2', B2': Name -> lone FileContents, Adirty, Bdirty: set Name | {
    IsValidFS[A] && IsValidFS[B]
    IsValidDirty[Adirty] && IsValidDirty[Bdirty]
    //DirtiesValid(A, B, Adirty, Bdirty)
    (A1' != A2'  || B1' != B2')
    SyncSpec[A, B, A1', B1', Adirty, Bdirty]
    SyncSpec[A, B, A2', B2', Adirty, Bdirty]
  }
}

run SyncSpecNotUnique for 5 expect 0




© 2015 - 2025 Weber Informatics LLC | Privacy Policy