Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456 Properties.hs
{-# OPTIONS -fglasgow-exts #-}importTinyWMimportData.MaybeimportData.Map(Map)importqualifiedData.MapasMimportqualifiedData.ListasLimportText.Show.FunctionsimportTest.QuickCheckimportDebug.Trace---------------------------------------------------------------------------- Building StackSets from lists--fromList::Orda=>(Int,[[a]])->StackSetafromList(_,[])=error"Cannot build a StackSet from an empty list"fromList(n,xs)|n<0||n>=lengthxs=error$"Cursor index is out of range: "++show(n,lengthxs)fromList(o,xs)=viewo$foldr(\(i,ys)s->foldr(\at->insertait)sys)(empty(lengthxs))(zip[0..]xs)-- flatten a stackset to a listtoList::StackSeta->(Int,[[a]])toListx=(currentx,mapsnd$M.toList(stacksx))-- ------------------------------------------------------------------------- Some useful predicates and helpers---- a window is a membermember::Orda=>a->StackSeta->Boolmemberkw=caseL.find((k`elem`).snd)(M.assocs(stacksw))ofNothing->False_->True-- | /O(n)/. Number of stackssize::T->Intsize=M.size.stacks-- | Height of stack 'n'height::Int->T->Intheightiw=length(indexiw)-- ------------------------------------------------------------------------- We need random Orderings, to pick random directions to shift focusinstanceArbitraryOrderingwherearbitrary=elements[LT,GT,EQ]---- And generate arbitrary stacksets--instance(Showa,Orda,Arbitrarya)=>Arbitrary(StackSeta)wherearbitrary=dosz<-choose(1,5)n<-choose(0,sz-1)ls<-vectorszlets=fromList(fromIntegraln,ls)returnsinstance(Orda,CoArbitrarya)=>CoArbitrary(StackSeta)wherecoarbitrarys=coarbitrary(toLists)---------------------------------------------------------------------------- constrain it to a simple element type--typeT=StackSetInt-- reflexiveprop_eq_refl(a::T)=a==aprop_eq_symm(a::T)b=a==b==>b==aprop_eq_tran(a::T)bc=a==b&&b==c==>a==cprop_eq_subs(a::T)bf=a==b==>fa==fbwhere_=f::T->T-------------------------------------------------------------------------- Invariants:---- * no element should ever appear more than once in a StackSet-- * the current index should always be valid---- All operations must preserve this.--invariant(w::T)=inBoundsw&&noDuplicates(concat$M.elems(stacksw))wherenoDuplicatesws=L.nubws==wsinBoundsx=currentx>=0&¤tx<szwheresz=M.size(stacksx)-- test generatorprop_invariant=invariantprop_empty_In=n>0==>invariant$emptynprop_view_In(x::T)=invariant$viewnxprop_rotate_In(x::T)=invariant$rotatenxprop_push_In(x::T)=invariant$pushnxprop_delete_In(x::T)=invariant$deletenxprop_shift_In(x::T)=n>=0&&n<sizex==>invariant$shiftnxprop_insert_Ini(x::T)=i>=0&&i<sizex==>invariant$insertnix-------------------------------------------------------------------------- empty StackSets have no windows in themprop_emptyn=n>0==>allnull(M.elems(stacksx))wherex=emptyn::T-- empty StackSets always have focus on workspace 0prop_empty_currentn=n>0==>currentx==0wherex=emptyn::T-------------------------------------------------------------------------- pushing a window into an empty stackset means that that window is now-- a member of the stacksetprop_pushin=n>0==>memberi(pushix)wherex=emptyn::T-- if i `notElem` x, then pop . push == idprop_push_pop(x::T)i=not(memberix)==>pop(pushix)==xwhere-- | Delete the currently focused windowpop::Orda=>StackSeta->StackSetapopw|Justk<-peekw=deletekw|otherwise=w-- push shouldn't change anything but the current workspaceprop_push_local(x::T)i=not(memberix)==>hiddenx==hidden(pushix)wherehiddenw=[indexnw|n<-[0..sz-1],n/=currentw]sz=M.size(stacksx)-- push is idempotentprop_push_idemi(x::T)=pushix==pushi(pushix)-- push is just insert on the current stackprop_push_insert(x::T)i=pushix==inserti(currentx)x-- pushing n new elements increases the size by nprop_size_push_nwsn=n>0==>size(foldrpushxws)==nwherex=emptyn::T-- pushing only adds to the height of the current stackprop_current_push_nisn=n>0==>height(currentx)(foldrpushxjs)==lengthjswherejs=L.nubisx=emptyn::T-- the value on top of the stack is the last element pushedprop_push_peek_n(x::T)is=not(nullis)==>fromJust(peek(foldrpushxis))==headis-- if a value is peekable, it is also a memberprop_peek_member(x::T)=isJust(peekx)==>member(fromJust(peekx))x-------------------------------------------------------------------------- delete removes windowsprop_delete(x::T)i=not(memberi(deleteix))-- deletion does nothing if 'x' is not in the thingprop_delete_uniqix=not(memberix)==>deleteix==xwhere_=x::T-- delete and push leave the original thingyprop_delete_pushix=not(memberix)==>deletei(pushix)==xwhere_=x::T-- deletion is idempotentprop_delete_idemi(x::T)=deleteix==deletei(deleteix)-------------------------------------------------------------------------- rotation is reversible in two directionsprop_rotaterotate1(x::T)=rotateLT(rotateGTx)==xprop_rotaterotate2(x::T)=rotateGT(rotateLTx)==x-- rotation through the height of a stack gets us back to the startprop_rotate_all(x::T)=foldr(\_y->rotateGTy)x[1..n]==xwheren=height(currentx)xprop_view_reversible(x::T)r=letn=currentxsz=sizexi=r`mod`szinviewn(view(fromIntegrali)x)==xwhere_=x::Tprop_view_idem(x::T)r=leti=fromIntegral$r`mod`szsz=sizexinviewi(viewix)==(viewix)prop_shift_reversibler(x::T)=leti=fromIntegral$r`mod`szsz=sizexn=currentxinheightnx>0==>(viewn.shiftn.viewi.shifti)x==x------------------------------------------------------------------------main=doletrunTsa=doprints;arunT"Eq"$doquickCheckprop_eq_reflquickCheckprop_eq_symmquickCheckprop_eq_tranquickCheckprop_eq_subsrunT"invariant"$doquickCheckprop_invariantquickCheckprop_empty_IquickCheckprop_view_IquickCheckprop_rotate_IquickCheckprop_push_IquickCheckprop_delete_IquickCheckprop_shift_IquickCheckprop_insert_IrunT"empty"$doquickCheckprop_emptyquickCheckprop_empty_currentrunT"push"$doquickCheckprop_pushquickCheckprop_push_popquickCheckprop_push_localquickCheckprop_push_insertquickCheckprop_size_push_nquickCheckprop_current_push_nquickCheckprop_push_idemrunT"delete"$doquickCheckprop_deletequickCheckprop_delete_uniqquickCheckprop_delete_pushrunT"peek"$doquickCheckprop_push_peek_nquickCheckprop_peek_memberquickCheckprop_delete_idemrunT"rotate"$doquickCheckprop_rotaterotate1quickCheckprop_rotaterotate2quickCheckprop_rotate_allrunT"view"$doquickCheckprop_view_reversiblequickCheckprop_view_idemrunT"shift"$doquickCheckprop_shift_reversible