Distributivity of Sequence Map over Function Composition in Dafny

Distributivity of Sequence Map over Function Composition in Dafny

lemma MapDistributivity(xs:seq<int>, f:int->int, g:int->int)
   requires forall x :: x in xs ==> f.requires(x);
   requires forall x :: x in xs ==> g.requires(f(x));
   ensures forall x :: x in MapSeq(xs,f) ==> g.requires(x);
   ensures MapSeq(MapSeq(xs,f), g) == MapSeq(xs, Compose(f,g));
{
   if xs != []
   {
     MapDistributivity(xs[1..], f, g);
   }
}
 
function Compose(f:int->int, g:int->int) : int->int
{
  x
    reads f.reads(x)
    reads if f.requires(x) then g.reads(f(x)) else {} 
    requires f.requires(x) 
    requires g.requires(f(x)) 
      -> g(f(x))
}
 
function MapSeq(xs:seq<int>, f:int->int) : seq<int>
   reads MapSeqReads(xs, f);
   requires forall x :: x in xs ==> f.requires(x);
   ensures |xs| == |MapSeq(xs,f)|;
   ensures forall x :: x in xs ==> f(x) in MapSeq(xs,f); 
{
  if xs == [] then []
  else [f(xs[0])] + MapSeq(xs[1..], f) 
}
 
function MapSeqReads(xs:seq<int>, f:int->int) : set<object>
   reads if |xs| > 0 then f.reads(xs[0]) + MapSeqReads(xs[1..], f) else {};
   decreases xs;
   ensures forall x :: x in xs ==> f.reads(x) <= MapSeqReads(xs,f); 
{
  if xs == [] then {}
  else f.reads(xs[0]) + MapSeqReads(xs[1..],f)
}

Leave a Reply