prv <- function(y, x)
{  
  # --------------------------------------------------
  # check inputs
  # --------------------------------------------------
  
  if(!is.numeric(y)){
    stop("y must be a nuemric vector\n")  
  }
  
  if(!is.matrix(x)){
    stop("x must be a matrix\n")  
  }
  
  if(ncol(x) < 2){
    stop("x must be a matrix with at least two columns\n")  
  }
  
  if(nrow(x) != length(y)){
    stop("x and y have different lengths\n")
  }
  
  if(any(sort(unique(y)) != c(0,1))){
    stop("y must be a binary vector with values 0 or 1\n")  
  }
  
  if(any(sort(unique(as.vector(x))) != c(0,1))){
    stop("x can only be 0 or 1\n")  
  }
  
  # --------------------------------------------------
  # count the number of 1s 
  # --------------------------------------------------
  n  = length(y)
  ny = sum(y)
  nx = ncol(x) 
  
  ns = apply(x, 2, sum)
  
  idxs <- function(c1){
    v=rep(0,nx)
    v[c1]=1
    v
  }
  
  counts <- function(c1){
    xx = x[,c1,drop=FALSE]
    xnew = drop(xx %*% rep(1, ncol(xx)) )
    length(which(xnew > 0))
  }
  
  idxL = cntL = list()
  
  idxL[[1]] = diag(nx)
  cntL[[1]] = ns
  
  for(i in 2:nx){
    comb1 = combn(nx, i)
    if(is.vector(comb1)){
      comb1 = matrix(comb1, ncol=1)
    }
    
    idxL[[i]] = apply(comb1, 2, idxs)
    cntL[[i]] = apply(comb1, 2, counts)
  }
  
  # --------------------------------------------------
  # calculate nominal p-value 
  # --------------------------------------------------
  
  alpha = 1.0
  
  for(i in 1:nx){
    idxLi = idxL[[i]]
    cntLi = cntL[[i]]
    
    for(j in 1:ncol(idxLi)){
      idxLij = (idxLi[,j] == 1)
      xnew = x[,idxLij,drop=FALSE]
      xnew   = drop(xnew %*% rep(1, ncol(xnew)))
      xnew[which(xnew > 1)] = 1
      
      m1   = sum(xnew*y)
      pval = phyper(m1-1, ny, n-ny, cntLi[j], lower.tail=FALSE)
      
      if(pval < alpha){ alpha = pval }
      
    }
  }
  
  alpha
  
}

  
