/**
 * Module containing utility strategies for the analysis.
 */
module php/strategy/const-prop/analysis/utilities
  
strategies  
  ZipAndAssignLists =
    ZipAndAssignLists(php-val-id-get-rule,php-val-id-add-rule)
  
  /**
   * Takes two lists, the first should contain either:
   * - None                - Some(List(_))
   * - Some(Variable(_))
   * The second should contain values.
   * It takes the first elements of these lists and tries to
   * assign the value to the variable, ignores it in case of a
   * None(), or performs a list-assign if there is a list.
   */
   ZipAndAssignLists(valid-get,valid-put|):
    ([],[]) -> ([],[])

   ZipAndAssignLists(valid-get,valid-put|):
    (_,[]) -> ([],[])

   ZipAndAssignLists(valid-get,valid-put|):
    ([],_) -> ([],[])

   ZipAndAssignLists(valid-get,valid-put|):
    ([None() | listtail], [ _ | arraytail]) -> result
      where result := <ZipAndAssignLists(valid-get,valid-put|)> (listtail,arraytail)

   ZipAndAssignLists(valid-get,valid-put|):
    ([Some(var@Variable(_)) | listtail], [ value | arraytail]) -> result
      where  <add-php-variable-rule(valid-put|)> (var,value)
           ; result := <ZipAndAssignLists(valid-get,valid-put|)> (listtail,arraytail)

   ZipAndAssignLists(valid-get,valid-put|):
    ([Some(list@List(_)) | listtail], [ value | arraytail]) -> result
      where  <eval-php-list-expression(valid-get,valid-put)> (list,value)
           ; result := <ZipAndAssignLists(valid-get,valid-put|)> (listtail,arraytail)
    
   /** 
    * Returns a list with all casings of a string.
    * @type String -> List(String)
    */
   all-casings =
      upper-case
    ; explode-string
    ; get-upper-and-lowercase
    ; map(implode-string)

    get-upper-and-lowercase =
     ?[x]
    ;![ [<to-upper> x] , [<to-lower> x]]

    get-upper-and-lowercase =
       ?[x | xs]
     ; xs'   := <get-upper-and-lowercase> xs
     ; upper := <map (\list -> <conc> ([<to-upper> x] , list ) \)> xs'
     ; lower := <map (\list -> <conc> ([<to-lower> x] , list ) \)> xs'
     ; <conc> (upper,lower)