text:
# Copyright 2018-2019, Carnegie Mellon University
# See LICENSE for details

Class(TMovingWindow, Tagged_tSPL_Container, rec(
  abbrevs := [(size, op) -> [size, op] ],
  dims := self >> self.params[2].dims(),
  transpose := self >> self,
  isReal := True
));

hf_size := var.fresh_t("t", TInt);

Class(HF, Tagged_tSPL_Container, rec(
  abbrevs := [(op, it) -> [op, it]],
  dims := self >> [self.params[1].dims()[1], hf_size],
  transpose := self >> self,
  isReal := True
));

Class(TBinOp, Tagged_tSPL_Container, rec(
    abbrevs :=  [(x, op, y)->[x, op, y] ],
    dims := self >> [self.params[3].dims()[1], self.params[3].dims()[2]*2 ],
    transpose := self >> self, #CopyFields(self, rec(transposed := not self.transposed)),
   isReal := True
));

NewRulesFor(TBinOp, rec(
  TBinOp_base := rec(
    forTransposition := false,
    applicable := (self, nt) >> true,
    children := nt -> [ nt.params ],
    apply := (t, c, nt) ->
     let(
       OLCompose(
         Reduction(t.dims()[1], op, 0, False)
       )
     )
  )
));

Class(TForAllInd, Tagged_tSPL_Container, rec(
    abbrevs :=  [ (ind, exp) -> Checked(IsVar(ind), IsSPL(exp), [ind, exp]) ],
    dims := self >> [self.params[2].dims()[1]*self.params[1].range, self.params[2].dims()[2]],
    transpose := self >> CopyFields(self, rec(transposed := not self.transposed)),
   isReal := True
));

Class(TComputeDist, Tagged_tSPL_Container, rec(
  abbrevs := [n -> Checked(IsInt(n), [n]) ],
  transpose := self >> CopyFields(self, rec(transposed := not self.transposed)),
  dims := self >> [1, self.params[1]],
  isReal := True
));

Class(TGreater, Tagged_tSPL_Container, rec(
    binop :=  (a,b)->_unwrap(gt(a,b)),
    lamdaop := (a,b) -> gt(a,b),
    abbrevs :=  [ (t1, t2) -> Checked(IsSPL(t1) and IsSPL(t2), [t1, t2]) ],
    transpose := self >> CopyFields(self, rec(transposed := not self.transposed)),
    dims := self >> [self.params[1].dims()[1], self.params[1].dims()[2] + self.params[2].dims()[2]],
    isReal := True,
    toOperator := self >> (vec -> let(a := vec{[1..self.params[1].dims()[2]]}, b := vec{[self.params[1].dims()[2]+1..self.dims()[2]]},
        o1 := self.params[1].toOperator(), o2 := self.params[2].toOperator(),
        List(Transposed([o1(a), o2(b)]), i->self.binop(i[1], i[2]))))
));

Class(TLessEqual, Tagged_tSPL_Container, rec(
    binop :=  (a,b)->_unwrap(leq(a,b)),
    lamdaop := (a,b) -> gt(b,a),
    abbrevs :=  [ (t1, t2) -> Checked(IsSPL(t1) and IsSPL(t2), [t1, t2]) ],
    transpose := self >> CopyFields(self, rec(transposed := not self.transposed)),
    dims := self >> [self.params[1].dims()[1], self.params[1].dims()[2] + self.params[2].dims()[2]],
    isReal := True,
    toOperator := self >> (vec -> let(a := vec{[1..self.params[1].dims()[2]]}, b := vec{[self.params[1].dims()[2]+1..self.dims()[2]]},
        o1 := self.params[1].toOperator(), o2 := self.params[2].toOperator(),
        List(Transposed([o1(a), o2(b)]), i->self.binop(i[1], i[2]))))
));

Class(TGreaterEqual, Tagged_tSPL_Container, rec(
    binop :=  (a,b)->_unwrap(geq(a,b)),
    lamdaop := (a,b) -> geq(a,b),
    abbrevs :=  [ (t1, t2) -> Checked(IsSPL(t1) and IsSPL(t2), [t1, t2]) ],
    transpose := self >> CopyFields(self, rec(transposed := not self.transposed)),
    dims := self >> [self.params[1].dims()[1], self.params[1].dims()[2] + self.params[2].dims()[2]],
    isReal := True,
    toOperator := self >> (vec -> let(a := vec{[1..self.params[1].dims()[2]]}, b := vec{[self.params[1].dims()[2]+1..self.dims()[2]]},
        o1 := self.params[1].toOperator(), o2 := self.params[2].toOperator(),
        List(Transposed([o1(a), o2(b)]), i->self.binop(i[1], i[2]))))
));

Class(TEqual, Tagged_tSPL_Container, rec(
    binop :=  (a,b)->_unwrap(eq(a,b)),
    lamdaop := (a,b) -> eq(a,b),
    abbrevs :=  [ (t1, t2) -> Checked(IsSPL(t1) and IsSPL(t2), [t1, t2]) ],
    transpose := self >> CopyFields(self, rec(transposed := not self.transposed)),
    dims := self >> [self.params[1].dims()[1], self.params[1].dims()[2] + self.params[2].dims()[2]],
    isReal := True,
    toOperator := self >> (vec -> let(a := vec{[1..self.params[1].dims()[2]]}, b := vec{[self.params[1].dims()[2]+1..self.dims()[2]]},
        o1 := self.params[1].toOperator(), o2 := self.params[2].toOperator(),
        List(Transposed([o1(a), o2(b)]), i->self.binop(i[1], i[2]))))
));

Class(TLess, Tagged_tSPL_Container, rec(
    binop :=  (a,b)->_unwrap(lt(a,b)),
    lamdaop := (a,b) -> geq(b,a),
    abbrevs :=  [ (t1, t2) -> Checked(IsSPL(t1) and IsSPL(t2), [t1, t2]) ],
    transpose := self >> CopyFields(self, rec(transposed := not self.transposed)),
    dims := self >> [self.params[1].dims()[1], self.params[1].dims()[2] + self.params[2].dims()[2]],
    isReal := True,
    toOperator := self >> (vec -> let(a := vec{[1..self.params[1].dims()[2]]}, b := vec{[self.params[1].dims()[2]+1..self.dims()[2]]},
        o1 := self.params[1].toOperator(), o2 := self.params[2].toOperator(),
        List(Transposed([o1(a), o2(b)]), i->self.binop(i[1], i[2]))))
));

Class(TEvalPolynomial, Tagged_tSPL_Container, rec(
    abbrevs :=  [ (n, s) -> Checked(IsInt(n), [n, s]) ],
    transpose := self >> CopyFields(self, rec(transposed := not self.transposed)),
    dims := self >> [1, 1],
    isReal := True,
    toOperator := self >> (vec -> [_unwrapVec(self.params[2]) * List([0..self.params[1]], i->vec[1]^i)])
));

Class(TDistance, Tagged_tSPL_Container, rec(
    abbrevs :=  [ s -> Checked(IsSPL(s), [s]) ],
    transpose := self >> CopyFields(self, rec(transposed := not self.transposed)),
    dims := self >> [1, 2*self.params[1].dims()[2]],
    isReal := True,
    toOperator := self >> (vec -> let(n:=Length(vec)/2, self.params[1].toOperator()(vec{[1..n]} - vec{[n+1..2*n]})))
));

Class(TPNorm, Tagged_tSPL_Container, rec(
    abbrevs :=  [ (n,p) -> Checked(IsInt(n) and IsInt(p), [n,p]) ],
    transpose := self >> CopyFields(self, rec(transposed := not self.transposed)),
    dims := self >> [1, self.params[1]],
    isReal := True,
    toOperator := self >> (vec -> [Double(Sum(List(vec, i->i^self.params[2])))^(1/self.params[2])])
));

Class(TInfinityNorm, Tagged_tSPL_Container, rec(
    abbrevs :=  [ n -> Checked(IsInt(n), [n]) ],
    transpose := self >> CopyFields(self, rec(transposed := not self.transposed)),
    dims := self >> [1, self.params[1]],
    isReal := True,
    toOperator := self >> (vec -> [Maximum(List(vec, AbsFloat))])
));

Class(TEvalLinSys, Tagged_tSPL_Container, rec(
    abbrevs :=  [ s -> Checked(IsSPL(s), [s]) ],
    transpose := self >> CopyFields(self, rec(transposed := not self.transposed)),
    dims := self >> [1, self.params[1].dims()[2]],
    isReal := True,
));

Class(TMatVecProd, Tagged_tSPL_Container, rec(
    abbrevs :=  [ s -> Checked(IsSPL(s) or IsExp(s), [s]) ],
    transpose := self >> CopyFields(self, rec(transposed := not self.transposed)),
    dims := self >> self.params[1].dims(),
    isReal := True
));

Class(TInsidePoly, Tagged_tSPL_Container, rec(
    abbrevs :=  [ s -> Checked(IsSPL(s), [s]) ],
    transpose := self >> CopyFields(self, rec(transposed := not self.transposed)),
    dims := self >> [1, self.params[1].dims()[2]],
    isReal := True,
    toOperator := self >> (vec -> ForAll(_unwrapMat(self.params[1].mat) * vec - _unwrapVec(self.params[1].rhs), i->i<0)),
));

Class(TForAnyInd, Tagged_tSPL_Container, rec(
    abbrevs :=  [ (ind, exp) -> Checked(IsVar(ind), IsSPL(exp), [ind, exp]) ],
    dims := self >> self.params[2].dims(),
    transpose := self >> CopyFields(self, rec(transposed := not self.transposed)),
    isReal := True,
    toOperator := self >> (vec -> [ForAny(List([0..self.params[1].range-1], j->RulesStrengthReduce(SubstVars(Copy(self.params[2]), rec((self.params[1].id) := V(j)))).toOperator()), cnd->cnd(vec))])
));

Class(TConstant, Tagged_tSPL_Container, rec(
   abbrevs := [x -> [x]],
   dims := self>>[1, 1],
   transpose := self >>  CopyFields(self, rec(transposed := not self.transposed)),
   isReal := True
));

if IsBound(AllClasses.TCond) then
    Unbind(AllClasses.TCond);
fi;

Class(TCond, Tagged_tSPL_Container, rec(
	abbrevs := [(test, body1, body2) -> Checked(IsSPL(test), IsSPL(body1), IsSPL(body2), [test, body1, body2])],
	dims := self >> self.params[1].dims(),
	transpose := self >> CopyFields(self, rec(transposed := not self.transposed)),
    isReal := True
));


text:
bogosort := function( list )

  while not IsSortedList( list ) do

    Shuffle( list );

  od;

  return list;

end;

ext: gi

max_stars_repo_name: Mynogs/Algorithm-Implementations

max_issues_repo_name: Mynogs/Algorithm-Implementations

max_forks_repo_name: Mynogs/Algorithm-Implementations


text:
# Copyright (c) 2018-2021, Carnegie Mellon University
# See LICENSE for details

#F SinDFT( <size> )
#F
Class(SinDFT, NonTerminal, rec(
    abbrevs   := [ n -> Checked(IsInt(n), n > 0, n) ],
    dims      := self >> [ self.params, self.params ],
    terminate := self >> Mat(Global.SinDFT(self.params)),
    transpose := self >> self,
    isReal    := True
));

#F CosDFT( <size> )
#F
Class(CosDFT, NonTerminal, rec(
    abbrevs   := [ n -> Checked(IsInt(n), n > 0, n) ],
    dims      := self >> [ self.params, self.params ],
    terminate := self >> Mat(Global.CosDFT(self.params)),
    transpose := self >> self,
    isReal    := True
));

RulesFor(CosDFT, rec(
    #F CosDFT_Base: (base case)
    #F
    #F   CosDFT_2 = F_2
    #F   CosDFT_4 = ... can be done in 5 instad of 7 adds
    #F
    CosDFT_Base := rec (
	info             := "CosDFT_2 -> F_2",
	forTransposition := false,
	isApplicable     := P -> P in [2,4],
	rule := (P, C) -> When(P=2, F(2),
	    Mat(MatSPL(copy1(2) * sums3(2))) *
	    DirectSum(F(2), Mat([[1, 1]])) *
	    Perm((2,3), 4))
    ),

    #F CosDFT_Trigonometric: 1984
    #F
    #F   CosDFT_n = copy * sums * (CosDFT_n/2 dirsum DCT2_n/4) * sums * perm
    #F
    #F   Vetterli/Nussbaumer:
    #F     Simple FFT and DCT Algorithms with Reduced Number
    #F     of Operations, Signal Processing, 1984, pp. 267--278
    #F
    CosDFT_Trigonometric := rec (
	info             := "CosDFT_n --> CosDFT_n/2, DCT2_n/4",
	isApplicable     := P -> P mod 4 = 0 and P > 4,

	allChildren := P -> [[ CosDFT(P/2), DCT2(P/4) ]],

	rule := (P, C) ->
	    copy1(P/2) * sums3(P/2) *
	    DirectSum(C) *
	    DirectSum(I(P/2), sums2(P/4)) *
	    L(P, 2)
    )
));

RulesFor(SinDFT, rec(
    #F SinDFT_Base: (base case)
    #F
    #F   SinDFT_2 = NullMat_2
    #F   SinDFT_4 = (NullMat_2 dirsum block) ^ perm
    #F
    SinDFT_Base := rec (
	info             := "SinDFT_2 -> 0_2",
	forTransposition := false,
	isApplicable := P -> P in [2,4],
	rule := (self, P, C) >> When(P = 2,
		Mat([[0,0],[0,0]]),
		DirectSum(Mat([[0, 0], [0, 0]]),
		          Mat([[1], [-1]]) * Mat([[1, -1]])) ^ Perm((2,3), 4))
    ),

    #F SinDFT_Trigonometric: 1984
    #F
    #F   SinDFT_n = copy * sums * (SinDFT_n/2 dirsum DCT2_n/4) * sums * perm
    #F
    #F   Vetterli/Nussbaumer:
    #F     Simple FFT and DCT Algorithms with Reduced Number
    #F     of Operations, Signal Processing, 1984, pp. 267--278
    #F
    SinDFT_Trigonometric := rec(
	info         := "SinDFT_n --> SinDFT_n/2, DCT2_n/4",
	isApplicable := P -> P mod 4 = 0 and P > 4,

	allChildren := P -> [[ SinDFT(P/2), DCT2(P/4) ]],

	rule := (P, C) ->
	    copy2(P/2) * sums5(P/2) *
	    DirectSum(C) *
	    DirectSum(I(P/2), sums4(P/4)) *
	    L(P, 2)
    )
));


text:
InstallMethod(RootSystem,
              "Root systems over the Integers",
              [IsString,IsPosInt],
              function(tip,rang)

              return RootSystem(SimpleLieAlgebra(tip,rang,Integers));
end);

InstallMethod(positiveRoots,
              "Positive roots in Chevalley basis order",
              [IsRootSystem],
              function(R)
              local cm;
              cm:=CartanMatrix(R);
              return List(PositiveRoots(R),i->SolutionMat(cm,i));
end);

InstallMethod(Cocharacters,
              "Cocharacters associated to positive roots",
              [IsLieAlgebra],
              function(L)
              local CB;

              CB:=ChevalleyBasis(L);

              return List([1..Length(CB[1])],i->CB[1][i]*CB[2][i]);
end);

InstallMethod(TorusWeightOnRoot,
              "The weight of a given torus on a given root",
              [IsRootSystem,IsList,IsPosInt],
              function(R,torus,root_index)
              local L,CB,B,h,e,roots,root;

              roots:=positiveRoots(R);
              roots:=Concatenation(roots,-roots);
              root:=roots[root_index];
              return Sum(List([1..Length(torus)],i->torus[i]*root[i]));
end);

InstallMethod(RootReflections,
              "Reflections in positive roots",
              [IsWeylGroup],
              function(W)
              local result,
              R,pr,pr_len,cm,roots,
              gens,unu,
              i,root,simple_ref,img,pos,
              check,rotire;

              R:=RootSystem(W);
              pr:=PositiveRoots(R);# these are the default GAP roots
              pr_len:=Length(pr);
              cm:=CartanMatrix(R);
              gens:=GeneratorsOfGroup(W);
              unu:=DiagonalMat(List([1..Length(gens)],i->1));
              result:=List([1..pr_len],i->unu);

              for i in [1..Length(gens)] do
                  result[i]:=gens[i];
              od;

              while Position(result,unu)<>fail do # this iteration is needed for G2
                  for root in [1..pr_len] do
                      for simple_ref  in Filtered([1..pr_len],i->result[i]<>unu) do
                          img:=pr[root]*result[simple_ref];
                          pos:=Position(pr,img);
                          if pos<>fail and
                             result[root]<>unu and
                             result[pos]=unu then
                             result[pos]:=result[simple_ref]^-1*result[root]*result[simple_ref];
                          fi;
                      od;
                  od;
              od;

              result:=List(result,i->cm*i*cm^-1);
              return result;
end);

InstallMethod(PositiveTorusPermutation,
              "The permutation that makes the torus have positive weights on simple roots",
              [IsRootSystem,IsList],
              function(R,t)
              local result,
              W,C,refs,
              next_root,i,lung,tmp;

              W:=WeylGroup(R);
              refs:=RootReflections(W);
              tmp:=List(t,i->i);

              next_root:=function(lista)
                  local i,lung;
                  lung:=Length(lista);
                  i:=1;
                  while i<=lung and lista[i]>=0 do i:=i+1; od;
                  return i;
              end;

              lung:=Length(tmp);
              i:=next_root(tmp);
              result:=[];
              while i<=lung do
                  Add(result,i);
                  tmp:=refs[i]*tmp;
                  i:=next_root(tmp);
              od;

              return result;
end);

InstallMethod(PermutationMatrix,
              "Matrix of permutation given by simple reflections",
              [IsWeylGroup,IsList],
              function(W,perm)
              local result,refs;

              refs:=RootReflections(W);

              if perm=[] then return DiagonalMat(List([1..Length(GeneratorsOfGroup(W))],i->1)); fi;
              return Product(List(Reversed(perm),i->refs[i]));
end);

InstallMethod(RootGraph,
              "root graph of level 1 roots",
              [IsRootSystem],
              function(R)
              local pr,rank,l0;

              rank:=Length(ChevalleyBasis(UnderlyingLieAlgebra(R))[3]);
              pr:=positiveRoots(R);
              l0:=pr{[1..rank]};

              return List(pr,root->List(Filtered(pr,i->i-root in l0),j->Position(pr,j)));
end);

InstallMethod(LatexRootGraph,
              "PGF&TikZ latex format of root graph",
              [IsString,IsRootSystem],
              function(fisier,R)
              local rank,type,pr,pr_len,
              l0,max_height,li,
              root_graph,coords,arrows,labels,alias,
              i,l;

              rank:=Length(ChevalleyBasis(UnderlyingLieAlgebra(R))[3]);
              type:=SemiSimpleType(UnderlyingLieAlgebra(R));
              pr:=positiveRoots(R);
              pr_len:=Length(pr);

              l0:=pr{[1..rank]};
              l0:=List(l0,i->Position(pr,i));
              max_height:=Sum(pr[pr_len]);
              li:=List([2..max_height],i->Filtered(pr,j->Sum(j)=i));
              li:=List(li,i->List(i,j->Position(pr,j)));

              Print(l0,"---",type,"\n");

              l:=Length(li[1]);
              coords:=List([1..Length(l0)],j->[l0[j],j,0]);
              coords:=Concatenation(coords,Concatenation(List([1..max_height-1],
                                                              i->List([1..Length(li[i])],j->[li[i][j],j,i]))));
              Print(coords,"\n----");
              Sort(coords,function(a,b) return a[1]<b[1]; end);
              coords:=List(coords,i->[i[2],i[3]]);

              Print(coords,"\n");

              root_graph:=RootGraph(R);
              arrows:=Concatenation(List([1..Length(root_graph)],i->List(root_graph[i],j->[i,j])));

              labels:=List(arrows,i->Position(pr,pr[i[2]]-pr[i[1]]));

              alias:=function(i)
                  if type = "F4" then return String(Concatenation(List(Permuted(pr[i],(4,2,1)),j->String(j)))); fi;
                  return String(Concatenation(List(pr[i],j->String(j))));
              end;

              PrintTo(fisier,"\\begin{tikzpicture}\n");

              # nodes:
              for i in [1..Length(coords)] do
#                 if proots[i][2]=1 then
#                     AppendTo(fisier,"\\node[draw,scale=0.5,color=red] (",i,") at (",
#                          2*coords[i][1],",",coords[i][2],") {",alias(i),": ",node_labels[i],"};\n");
#                 else
                 AppendTo(fisier,"\\node[draw,scale=0.5] (",i,") at (",
                          2*coords[i][1],",",coords[i][2],") {",i,": ",alias(i),"};\n");
#                 fi;
              od;

              # arrows
              for i in [1..Length(arrows)] do
#                  AppendTo(fisier,"\\draw[->,>=stealth] (",arrows[i][1],") -- (",arrows[i][2],
#                           ") node [right,near end,scale=0.5] {",labels[i],"};\n");
                  AppendTo(fisier,"\\draw[->,>=stealth] (",arrows[i][1],") -- (",arrows[i][2],");\n");
              od;

              AppendTo(fisier,"\\end{tikzpicture}\n");
end);


text:
IsSymInf := x -> IsSymbolic(x) and IsBound(x.isSymInf) and x.isSymInf;

Class(SymInf, Symbolic, rec(
  __call__ := (self, t) >> WithBases(self, rec(
    t := Checked(IsType(t), t),
    operations := rec(Print := x-> When(IsBound(x.print), x.print(), Print(x.__name__)))
  )),
  print := self >> Print(self.__name__, "(", self.t, ")"),
  isSymInf := true,
  isValue := true,
  ev := self >> self,
  computeType := self >> self.t
));

# ==========================================================================
# Semiring
# ==========================================================================

IsSemiring := x -> IsType(x) and IsBound(x.isSemiring) and x.isSemiring;

IsSemiring_Arithmetic := x -> IsSemiring(x) and IsBound(x.isSemiring_Arithmetic) and x.isSemiring_Arithmetic;

IsSemiring_MinPlus := x -> IsSemiring(x) and IsBound(x.isSemiring_MinPlus) and x.isSemiring_MinPlus;

IsSemiring_MinTimes := x -> IsSemiring(x) and IsBound(x.IsSemiring_MinTimes) and x.isSemiring_MinTimes;

isSemiring_Boolean := x -> IsSemiring(x) and IsBound(x.isSemiring_Boolean) and x.isSemiring_Boolean;

Class(TSemiring, CompositeTyp, rec(
  __call__ := (self, t) >> WithBases(self, rec(
    t := Checked(IsType(t), t),
    operations := TypOps
  )),
  base_t := self >> self.t,
  isSemiring := true,

  print := self >> Print(self.__name__, "(", self.t, ")"),

  check := (self, v) >> Cond(
    UnifyTypes([self.t, InferType(v)]) = self.t,
      v,
    Error("type mismatch: semiring is type ", self.t)
  ),

  rChildren := self >> [self.t],
  rSetChild := rSetChildFields("t"),
  from_rChildren := (self, rch) >> self,

  zero := self >> Error("method on undefined semiring"),
  one := self >> Error("method on undefined semiring"),

  sum := self >> Error("method on undefined semiring"),
  product := self >> Error("method on undefined semiring")
));

Class(TSemiring_Arithmetic, TSemiring, rec(
  zero := self >> self.t.zero(),
  one := self >> self.t.one(),

  sum := (self, v1, v2) >> Cond(
    UnifyTypes([self.t, InferType(v1), InferType(v2)]) = self.t,
      self.t.sum(v1, v2),
    Error("type mismatch: semiring is type ", self.t)
  ),
  product := (self, v1, v2) >> Cond(
    UnifyTypes([self.t, InferType(v1), InferType(v2)]) = self.t,
      self.t.product(v1, v2),
    Error("type mismatch: semiring is type ", self.t)
  ),

  OpenMP_sum := "+",
  OpenMP_product := "*",

  isSemiring_Arithmetic := true
));

Class(TSemiring_MinPlus, TSemiring, rec(
  zero := self >> SymInf(self.t),
  one := self >> self.t.zero(),

  sum := (self, v1, v2) >> Cond(
    IsSymInf(v1) and IsSymInf(v2),
      SymInf(self.t),
    IsSymInf(v1) and UnifyTypes([self.t, v2.t]) = self.t,
      v2,
    IsSymInf(v2) and UnifyTypes([self.t, v1.t]) = self.t,
      v1,
    UnifyTypes([self.t, InferType(v1), InferType(v2)]) = self.t,
      min(v1, v2),
    Error("type mismatch: semiring is type ", self.t)
  ),
  product := (self, v1, v2) >> Cond(
    IsSymInf(v1) or IsSymInf(v2),
      SymInf(self.t),
    UnifyTypes([self.t, InferType(v1), InferType(v2)]) = self.t,
      self.t.sum(v1, v2),
    Error("type mismatch: semiring is type ", self.t)
  ),

  OpenMP_sum := "min",
  OpenMP_product := "+",

  isSemiring_MinPlus := true
));

Class(TSemiring_MinTimes, TSemiring, rec(
  zero := self >> SymInf(self.t),
  one := self >> self.t.zero(),

  sum := (self, v1, v2) >> Cond(
    IsSymInf(v1) and IsSymInf(v2),
      SymInf(self.t),
    IsSymInf(v1) and UnifyTypes([self.t, v2.t]) = self.t,
      v2,
    IsSymInf(v2) and UnifyTypes([self.t, v1.t]) = self.t,
      v1,
    UnifyTypes([self.t, InferType(v1), InferType(v2)]) = self.t,
      min(v1, v2),
    Error("type mismatch: semiring is type ", self.t)
  ),
  product := (self, v1, v2) >> Cond(
    UnifyTypes([self.t, InferType(v1), InferType(v2)]) = self.t,
      self.t.product(v1, v2),
    Error("type mismatch: semiring is type ", self.t)
  ),

  OpenMP_sum := "min",
  OpenMP_product := "*",

  isSemiring_MinTimes := true
));

Class(TSemiring_Boolean, TSemiring, rec(
  zero := self >> self.t.zero(),
  one := self >> self.t.one(),

  sum := (self, v1, v2) >> Cond(let(
    l := UnifyTypes([self.t, InferType(v1), InferType(v2)]), Cond(IsArrayT(l), l.t = self.t, l = self.t)),
      logic_or(v1, v2),
    Error("type mismatch: semiring is type ", self.t)
  ),
  product := (self, v1, v2) >> Cond(let(
    l := UnifyTypes([self.t, InferType(v1), InferType(v2)]), Cond(IsArrayT(l), l.t = self.t, l = self.t)),
      logic_and(v1,v2),
    Error("type mismatch: semiring is type ", self.t)
  ),

  OpenMP_sum := "||",
  OpenMP_product := "&&",

  isSemiring_Boolean := true
));


text:
# Copyright (c) 2018-2021, Carnegie Mellon University
# See LICENSE for details

SSE_2x64f.setRules(rec(
  binrules := [ rec(
          perm := rec(
              spl := L(4, 2),
              l := 1,
              N := 4,
              n := 2,
              r := 1 ),
          instr := [ rec(
                  instr := vunpacklo_2x64f,
                  p := [  ] ), rec(
                  instr := vunpackhi_2x64f,
                  p := [  ] ) ],
          v := 2,
          vperm := VPerm(L(4, 2), (y, x) -> chain(assign(vref(y, 0, 2), vunpacklo_2x64f(vref(x, 0, 2), vref(x, 2, 2), [  ])), assign(vref(y, 2, 2), vunpackhi_2x64f(vref(x, 0, 2), vref(x, 2, 2), [  ]))), 2, 2) ) ],
  unrules := [  ],
  x_I_vby2 := [ [ rec(
              instr := vunpacklo_2x64f,
              p := [  ] ), rec(
              instr := vshuffle_2x64f,
              p := [ 1, 2 ] ) ], [ rec(
              instr := vshuffle_2x64f,
              p := [ 2, 1 ] ), rec(
              instr := vunpackhi_2x64f,
              p := [  ] ) ] ] ));
SSE_2x64i.setRules(rec(
  binrules := [ rec(
          perm := rec(
              spl := L(4, 2),
              l := 1,
              N := 4,
              n := 2,
              r := 1 ),
          instr := [ rec(
                  instr := vunpacklo_2x64i,
                  p := [  ] ), rec(
                  instr := vunpackhi_2x64i,
                  p := [  ] ) ],
          v := 2,
          vperm := VPerm(L(4, 2), (y, x) -> chain(assign(vref(y, 0, 2), vunpacklo_2x64i(vref(x, 0, 2), vref(x, 2, 2), [  ])), assign(vref(y, 2, 2), vunpackhi_2x64i(vref(x, 0, 2), vref(x, 2, 2), [  ]))), 2, 2) ) ],
  unrules := [  ],
  x_I_vby2 := [ [ rec(
              instr := vunpacklo_2x64i,
              p := [  ] ), rec(
              instr := vshuffle_2x64i,
              p := [ 1, 2 ] ) ], [ rec(
              instr := vshuffle_2x64i,
              p := [ 2, 1 ] ), rec(
              instr := vunpackhi_2x64i,
              p := [  ] ) ] ] ));
SSE_2x32f.setRules(rec(
  binrules := [ rec(
          perm := rec(
              spl := L(4, 2),
              l := 1,
              N := 4,
              n := 2,
              r := 1 ),
          instr := [ rec(
                  instr := vunpacklo_2x32f,
                  p := [  ] ), rec(
                  instr := vunpackhi_2x32f,
                  p := [  ] ) ],
          v := 2,
          vperm := VPerm(L(4, 2), (y, x) -> chain(assign(vref(y, 0, 2), vunpacklo_2x32f(vref(x, 0, 2), vref(x, 2, 2), [  ])), assign(vref(y, 2, 2), vunpackhi_2x32f(vref(x, 0, 2), vref(x, 2, 2), [  ]))), 2, 2) ) ],
  unrules := [  ],
  x_I_vby2 := [ [ rec(
              instr := vunpacklo_2x32f,
              p := [  ] ), rec(
              instr := vshuffle_2x32f,
              p := [ 1, 2 ] ) ], [ rec(
              instr := vshuffle_2x32f,
              p := [ 2, 1 ] ), rec(
              instr := vunpackhi_2x32f,
              p := [  ] ) ] ] ));
SSE_4x32f.setRules(rec(
  binrules := [ rec(
          perm := rec(
              spl := L(8, 4),
              l := 1,
              N := 8,
              n := 4,
              r := 1 ),
          instr := [ rec(
                  instr := vunpacklo_4x32f,
                  p := [  ] ), rec(
                  instr := vunpackhi_4x32f,
                  p := [  ] ) ],
          v := 4,
          vperm := VPerm(L(8, 4), (y, x) -> chain(assign(vref(y, 0, 4), vunpacklo_4x32f(vref(x, 0, 4), vref(x, 4, 4), [  ])), assign(vref(y, 4, 4), vunpackhi_4x32f(vref(x, 0, 4), vref(x, 4, 4), [  ]))), 4, 2) ), rec(
          perm := rec(
              spl := Tensor(
                  L(4, 2),
                  I(2)
                ),
              l := 1,
              N := 4,
              n := 2,
              r := 2 ),
          instr := [ rec(
                  instr := vshuffle_4x32f,
                  p := [ 1, 2, 1, 2 ] ), rec(
                  instr := vshuffle_4x32f,
                  p := [ 3, 4, 3, 4 ] ) ],
          v := 4,
          vperm := VPerm(Tensor(
                L(4, 2),
                I(2)
              ), (y, x) -> chain(assign(vref(y, 0, 4), vshuffle_4x32f(vref(x, 0, 4), vref(x, 4, 4), [ 1, 2, 1, 2 ])), assign(vref(y, 4, 4), vshuffle_4x32f(vref(x, 0, 4), vref(x, 4, 4), [ 3, 4, 3, 4 ]))), 4, 2) ), rec(
          perm := rec(
              spl := L(8, 2),
              l := 1,
              N := 8,
              n := 2,
              r := 1 ),
          instr := [ rec(
                  instr := vshuffle_4x32f,
                  p := [ 1, 3, 1, 3 ] ), rec(
                  instr := vshuffle_4x32f,
                  p := [ 2, 4, 2, 4 ] ) ],
          v := 4,
          vperm := VPerm(L(8, 2), (y, x) -> chain(assign(vref(y, 0, 4), vshuffle_4x32f(vref(x, 0, 4), vref(x, 4, 4), [ 1, 3, 1, 3 ])), assign(vref(y, 4, 4), vshuffle_4x32f(vref(x, 0, 4), vref(x, 4, 4), [ 2, 4, 2, 4 ]))), 4, 2) ), rec(
          perm := rec(
              spl := Tensor(
                  I(2),
                  L(4, 2)
                ),
              l := 2,
              N := 4,
              n := 2,
              r := 1 ),
          instr := [ rec(
                  instr := vshuffle_4x32f,
                  p := [ 1, 3, 1, 3 ] ), rec(
                  instr := vshuffle_4x32f,
                  p := [ 2, 4, 2, 4 ] ) ],
          v := 4,
          vperm := VPerm(Tensor(
                L(4, 2),
                I(2)
              ), (y, x) -> chain(assign(vref(y, 0, 4), vshuffle_4x32f(vref(x, 0, 4), vref(x, 4, 4), [ 1, 2, 1, 2 ])), assign(vref(y, 4, 4), vshuffle_4x32f(vref(x, 0, 4), vref(x, 4, 4), [ 3, 4, 3, 4 ]))), 4, 2) *
            VPerm(Tensor(
                L(4, 2),
                I(2)
              ) *
              Tensor(
                I(2),
                L(4, 2)
              ), (y, x) -> chain(assign(vref(y, 0, 4), vshuffle_4x32f(vref(x, 0, 4), vref(x, 4, 4), [ 1, 3, 1, 3 ])), assign(vref(y, 4, 4), vshuffle_4x32f(vref(x, 0, 4), vref(x, 4, 4), [ 2, 4, 2, 4 ]))), 4, 4.2000000000000002) *
            VTensor(I(2), 4) ), rec(
          perm := rec(
              spl := Tensor(
                  I(2),
                  L(4, 2)
                ),
              l := 2,
              N := 4,
              n := 2,
              r := 1 ),
          instr := [ rec(
                  instr := vunpacklo_4x32f,
                  p := [  ] ), rec(
                  instr := vunpackhi_4x32f,
                  p := [  ] ) ],
          v := 4,
          vperm := VTensor(I(2), 4) *
            VPerm(Tensor(
                I(2),
                L(4, 2)
              ) *
              Tensor(
                L(4, 2),
                I(2)
              ), (y, x) -> chain(assign(vref(y, 0, 4), vunpacklo_4x32f(vref(x, 0, 4), vref(x, 4, 4), [  ])), assign(vref(y, 4, 4), vunpackhi_4x32f(vref(x, 0, 4), vref(x, 4, 4), [  ]))), 4, 4.2000000000000002) *
            VPerm(Tensor(
                L(4, 2),
                I(2)
              ), (y, x) -> chain(assign(vref(y, 0, 4), vshuffle_4x32f(vref(x, 0, 4), vref(x, 4, 4), [ 1, 2, 1, 2 ])), assign(vref(y, 4, 4), vshuffle_4x32f(vref(x, 0, 4), vref(x, 4, 4), [ 3, 4, 3, 4 ]))), 4, 2) ) ],
  unrules := [ rec(
          perm := rec(
              spl := L(4, 2),
              l := 1,
              N := 4,
              n := 2,
              r := 1 ),
          instr := rec(
              instr := vushuffle_4x32f,
              p := [ 1, 3, 2, 4 ] ),
          v := 4,
          vperm := VPerm(L(4, 2), (y, x) -> assign(vref(y, 0, 4), vushuffle_4x32f(vref(x, 0, 4), [ 1, 3, 2, 4 ])), 4, 0.90000000000000002) ) ],
  x_I_vby2 := [ [ rec(
              instr := vshuffle_4x32f,
              p := [ 1, 2, 1, 2 ] ), rec(
              instr := vshuffle_4x32f,
              p := [ 1, 2, 3, 4 ] ) ], [ rec(
              instr := vshuffle_4x32f,
              p := [ 3, 4, 1, 2 ] ), rec(
              instr := vshuffle_4x32f,
              p := [ 3, 4, 3, 4 ] ) ] ] ));
SSE_4x32i.setRules(rec(
  binrules := [ rec(
          perm := rec(
              spl := L(8, 4),
              l := 1,
              N := 8,
              n := 4,
              r := 1 ),
          instr := [ rec(
                  instr := vunpacklo_4x32i,
                  p := [  ] ), rec(
                  instr := vunpackhi_4x32i,
                  p := [  ] ) ],
          v := 4,
          vperm := VPerm(L(8, 4), (y, x) -> chain(assign(vref(y, 0, 4), vunpacklo_4x32i(vref(x, 0, 4), vref(x, 4, 4), [  ])), assign(vref(y, 4, 4), vunpackhi_4x32i(vref(x, 0, 4), vref(x, 4, 4), [  ]))), 4, 2) ), rec(
          perm := rec(
              spl := Tensor(
                  L(4, 2),
                  I(2)
                ),
              l := 1,
              N := 4,
              n := 2,
              r := 2 ),
          instr := [ rec(
                  instr := vshuffle_4x32i,
                  p := [ 1, 2, 1, 2 ] ), rec(
                  instr := vshuffle_4x32i,
                  p := [ 3, 4, 3, 4 ] ) ],
          v := 4,
          vperm := VPerm(Tensor(
                L(4, 2),
                I(2)
              ), (y, x) -> chain(assign(vref(y, 0, 4), vshuffle_4x32i(vref(x, 0, 4), vref(x, 4, 4), [ 1, 2, 1, 2 ])), assign(vref(y, 4, 4), vshuffle_4x32i(vref(x, 0, 4), vref(x, 4, 4), [ 3, 4, 3, 4 ]))), 4, 2) ), rec(
          perm := rec(
              spl := L(8, 2),
              l := 1,
              N := 8,
              n := 2,
              r := 1 ),
          instr := [ rec(
                  instr := vshuffle_4x32i,
                  p := [ 1, 3, 1, 3 ] ), rec(
                  instr := vshuffle_4x32i,
                  p := [ 2, 4, 2, 4 ] ) ],
          v := 4,
          vperm := VPerm(L(8, 2), (y, x) -> chain(assign(vref(y, 0, 4), vshuffle_4x32i(vref(x, 0, 4), vref(x, 4, 4), [ 1, 3, 1, 3 ])), assign(vref(y, 4, 4), vshuffle_4x32i(vref(x, 0, 4), vref(x, 4, 4), [ 2, 4, 2, 4 ]))), 4, 2) ), rec(
          perm := rec(
              spl := Tensor(
                  I(2),
                  L(4, 2)
                ),
              l := 2,
              N := 4,
              n := 2,
              r := 1 ),
          instr := [ rec(
                  instr := vshuffle_4x32i,
                  p := [ 1, 3, 1, 3 ] ), rec(
                  instr := vshuffle_4x32i,
                  p := [ 2, 4, 2, 4 ] ) ],
          v := 4,
          vperm := VPerm(Tensor(
                L(4, 2),
                I(2)
              ), (y, x) -> chain(assign(vref(y, 0, 4), vshuffle_4x32i(vref(x, 0, 4), vref(x, 4, 4), [ 1, 2, 1, 2 ])), assign(vref(y, 4, 4), vshuffle_4x32i(vref(x, 0, 4), vref(x, 4, 4), [ 3, 4, 3, 4 ]))), 4, 2) *
            VPerm(Tensor(
                L(4, 2),
                I(2)
              ) *
              Tensor(
                I(2),
                L(4, 2)
              ), (y, x) -> chain(assign(vref(y, 0, 4), vshuffle_4x32i(vref(x, 0, 4), vref(x, 4, 4), [ 1, 3, 1, 3 ])), assign(vref(y, 4, 4), vshuffle_4x32i(vref(x, 0, 4), vref(x, 4, 4), [ 2, 4, 2, 4 ]))), 4, 4.2000000000000002) *
            VTensor(I(2), 4) ), rec(
          perm := rec(
              spl := Tensor(
                  I(2),
                  L(4, 2)
                ),
              l := 2,
              N := 4,
              n := 2,
              r := 1 ),
          instr := [ rec(
                  instr := vunpacklo_4x32i,
                  p := [  ] ), rec(
                  instr := vunpackhi_4x32i,
                  p := [  ] ) ],
          v := 4,
          vperm := VTensor(I(2), 4) *
            VPerm(Tensor(
                I(2),
                L(4, 2)
              ) *
              Tensor(
                L(4, 2),
                I(2)
              ), (y, x) -> chain(assign(vref(y, 0, 4), vunpacklo_4x32i(vref(x, 0, 4), vref(x, 4, 4), [  ])), assign(vref(y, 4, 4), vunpackhi_4x32i(vref(x, 0, 4), vref(x, 4, 4), [  ]))), 4, 4.2000000000000002) *
            VPerm(Tensor(
                L(4, 2),
                I(2)
              ), (y, x) -> chain(assign(vref(y, 0, 4), vshuffle_4x32i(vref(x, 0, 4), vref(x, 4, 4), [ 1, 2, 1, 2 ])), assign(vref(y, 4, 4), vshuffle_4x32i(vref(x, 0, 4), vref(x, 4, 4), [ 3, 4, 3, 4 ]))), 4, 2) ) ],
  unrules := [ rec(
          perm := rec(
              spl := L(4, 2),
              l := 1,
              N := 4,
              n := 2,
              r := 1 ),
          instr := rec(
              instr := vushuffle_4x32i,
              p := [ 1, 3, 2, 4 ] ),
          v := 4,
          vperm := VPerm(L(4, 2), (y, x) -> assign(vref(y, 0, 4), vushuffle_4x32i(vref(x, 0, 4), [ 1, 3, 2, 4 ])), 4, 0.90000000000000002) ) ],
  x_I_vby2 := [ [ rec(
              instr := vshuffle_4x32i,
              p := [ 1, 2, 1, 2 ] ), rec(
              instr := vshuffle_4x32i,
              p := [ 1, 2, 3, 4 ] ) ], [ rec(
              instr := vshuffle_4x32i,
              p := [ 3, 4, 1, 2 ] ), rec(
              instr := vshuffle_4x32i,
              p := [ 3, 4, 3, 4 ] ) ] ] ));
SSE_8x16i.setRules(rec(
  binrules := [ rec(
          perm := rec(
              spl := L(16, 8),
              l := 1,
              N := 16,
              n := 8,
              r := 1 ),
          instr := [ rec(
                  instr := vunpacklo_8x16i,
                  p := [  ] ), rec(
                  instr := vunpackhi_8x16i,
                  p := [  ] ) ],
          v := 8,
          vperm := VPerm(L(16, 8), (y, x) -> chain(assign(vref(y, 0, 8), vunpacklo_8x16i(vref(x, 0, 8), vref(x, 8, 8), [  ])), assign(vref(y, 8, 8), vunpackhi_8x16i(vref(x, 0, 8), vref(x, 8, 8), [  ]))), 8, 2) ), rec(
          perm := rec(
              spl := Tensor(
                  L(8, 4),
                  I(2)
                ),
              l := 1,
              N := 8,
              n := 4,
              r := 2 ),
          instr := [ rec(
                  instr := vunpacklo2_8x16i,
                  p := [  ] ), rec(
                  instr := vunpackhi2_8x16i,
                  p := [  ] ) ],
          v := 8,
          vperm := VPerm(Tensor(
                L(8, 4),
                I(2)
              ), (y, x) -> chain(assign(vref(y, 0, 8), vunpacklo2_8x16i(vref(x, 0, 8), vref(x, 8, 8), [  ])), assign(vref(y, 8, 8), vunpackhi2_8x16i(vref(x, 0, 8), vref(x, 8, 8), [  ]))), 8, 2) ), rec(
          perm := rec(
              spl := Tensor(
                  L(4, 2),
                  I(4)
                ),
              l := 1,
              N := 4,
              n := 2,
              r := 4 ),
          instr := [ rec(
                  instr := vunpacklo4_8x16i,
                  p := [  ] ), rec(
                  instr := vunpackhi4_8x16i,
                  p := [  ] ) ],
          v := 8,
          vperm := VPerm(Tensor(
                L(4, 2),
                I(4)
              ), (y, x) -> chain(assign(vref(y, 0, 8), vunpacklo4_8x16i(vref(x, 0, 8), vref(x, 8, 8), [  ])), assign(vref(y, 8, 8), vunpackhi4_8x16i(vref(x, 0, 8), vref(x, 8, 8), [  ]))), 8, 2) ), rec(
          perm := rec(
              spl := Tensor(
                  L(8, 2),
                  I(2)
                ),
              l := 1,
              N := 8,
              n := 2,
              r := 2 ),
          instr := [ rec(
                  instr := vshuffle2_8x16i,
                  p := [ 1, 3, 1, 3 ] ), rec(
                  instr := vshuffle2_8x16i,
                  p := [ 2, 4, 2, 4 ] ) ],
          v := 8,
          vperm := VPerm(Tensor(
                L(8, 2),
                I(2)
              ), (y, x) -> chain(assign(vref(y, 0, 8), vshuffle2_8x16i(vref(x, 0, 8), vref(x, 8, 8), [ 1, 3, 1, 3 ])), assign(vref(y, 8, 8), vshuffle2_8x16i(vref(x, 0, 8), vref(x, 8, 8), [ 2, 4, 2, 4 ]))), 8, 2) ), rec(
          perm := rec(
              spl := Tensor(
                  I(2),
                  L(4, 2),
                  I(2)
                ),
              l := 2,
              N := 4,
              n := 2,
              r := 2 ),
          instr := [ rec(
                  instr := vshuffle2_8x16i,
                  p := [ 1, 3, 1, 3 ] ), rec(
                  instr := vshuffle2_8x16i,
                  p := [ 2, 4, 2, 4 ] ) ],
          v := 8,
          vperm := VPerm(Tensor(
                L(4, 2),
                I(4)
              ), (y, x) -> chain(assign(vref(y, 0, 8), vunpacklo4_8x16i(vref(x, 0, 8), vref(x, 8, 8), [  ])), assign(vref(y, 8, 8), vunpackhi4_8x16i(vref(x, 0, 8), vref(x, 8, 8), [  ]))), 8, 2) *
            VPerm(Tensor(
                L(4, 2),
                I(4)
              ) *
              Tensor(
                I(2),
                L(4, 2),
                I(2)
              ), (y, x) -> chain(assign(vref(y, 0, 8), vshuffle2_8x16i(vref(x, 0, 8), vref(x, 8, 8), [ 1, 3, 1, 3 ])), assign(vref(y, 8, 8), vshuffle2_8x16i(vref(x, 0, 8), vref(x, 8, 8), [ 2, 4, 2, 4 ]))), 8, 4.2000000000000002) *
            VTensor(I(2), 8) ), rec(
          perm := rec(
              spl := Tensor(
                  I(2),
                  L(8, 4)
                ),
              l := 2,
              N := 8,
              n := 4,
              r := 1 ),
          instr := [ rec(
                  instr := vunpacklo_8x16i,
                  p := [  ] ), rec(
                  instr := vunpackhi_8x16i,
                  p := [  ] ) ],
          v := 8,
          vperm := VTensor(I(2), 8) *
            VPerm(Tensor(
                I(2),
                L(8, 4)
              ) *
              Tensor(
                L(4, 2),
                I(4)
              ), (y, x) -> chain(assign(vref(y, 0, 8), vunpacklo_8x16i(vref(x, 0, 8), vref(x, 8, 8), [  ])), assign(vref(y, 8, 8), vunpackhi_8x16i(vref(x, 0, 8), vref(x, 8, 8), [  ]))), 8, 4.2000000000000002) *
            VPerm(Tensor(
                L(4, 2),
                I(4)
              ), (y, x) -> chain(assign(vref(y, 0, 8), vunpacklo4_8x16i(vref(x, 0, 8), vref(x, 8, 8), [  ])), assign(vref(y, 8, 8), vunpackhi4_8x16i(vref(x, 0, 8), vref(x, 8, 8), [  ]))), 8, 2) ), rec(
          perm := rec(
              spl := Tensor(
                  I(2),
                  L(4, 2),
                  I(2)
                ),
              l := 2,
              N := 4,
              n := 2,
              r := 2 ),
          instr := [ rec(
                  instr := vunpacklo2_8x16i,
                  p := [  ] ), rec(
                  instr := vunpackhi2_8x16i,
                  p := [  ] ) ],
          v := 8,
          vperm := VTensor(I(2), 8) *
            VPerm(Tensor(
                I(2),
                L(4, 2),
                I(2)
              ) *
              Tensor(
                L(4, 2),
                I(4)
              ), (y, x) -> chain(assign(vref(y, 0, 8), vunpacklo2_8x16i(vref(x, 0, 8), vref(x, 8, 8), [  ])), assign(vref(y, 8, 8), vunpackhi2_8x16i(vref(x, 0, 8), vref(x, 8, 8), [  ]))), 8, 4.2000000000000002) *
            VPerm(Tensor(
                L(4, 2),
                I(4)
              ), (y, x) -> chain(assign(vref(y, 0, 8), vunpacklo4_8x16i(vref(x, 0, 8), vref(x, 8, 8), [  ])), assign(vref(y, 8, 8), vunpackhi4_8x16i(vref(x, 0, 8), vref(x, 8, 8), [  ]))), 8, 2) ) ],
  unrules := [ rec(
          perm := rec(
              spl := Tensor(
                  L(4, 2),
                  I(2)
                ),
              l := 1,
              N := 4,
              n := 2,
              r := 2 ),
          instr := rec(
              instr := vushuffle2_8x16i,
              p := [ 1, 3, 2, 4 ] ),
          v := 8,
          vperm := VPerm(Tensor(
                L(4, 2),
                I(2)
              ), (y, x) -> assign(vref(y, 0, 8), vushuffle2_8x16i(vref(x, 0, 8), [ 1, 3, 2, 4 ])), 8, 0.90000000000000002) ), rec(
          perm := rec(
              spl := Tensor(
                  I(2),
                  L(4, 2)
                ),
              l := 2,
              N := 4,
              n := 2,
              r := 1 ),
          instr := [ rec(
                  instr := vushufflelo_8x16i,
                  p := [ 1, 3, 2, 4 ] ), rec(
                  instr := vushufflehi_8x16i,
                  p := [ 1, 3, 2, 4 ] ) ],
          v := 8,
          vperm := VPerm(Tensor(
                I(2),
                L(4, 2)
              ), (y, x) -> Let(t => TempVec(TArray(x.t.t, Eval(v))),
               decl(t, chain(assign(vref(t, 0, Eval(v)), Eval(i1)(vref(x, 0, Eval(v)), Eval(op1.p))), assign(vref(y, 0, Eval(v)), Eval(i2)(vref(t, 0, Eval(v)), Eval(op2.p))))) )
             , 8, 1.8) ) ],
  x_I_vby2 := [ [ rec(
              instr := vunpacklo4_8x16i,
              p := [  ] ), rec(
              instr := vshuffle2_8x16i,
              p := [ 1, 2, 3, 4 ] ) ], [ rec(
              instr := vshuffle2_8x16i,
              p := [ 3, 4, 1, 2 ] ), rec(
              instr := vunpackhi4_8x16i,
              p := [  ] ) ] ] ));
SSE_16x8i.setRules(rec(
  binrules := [ rec(
          perm := rec(
              spl := L(32, 16),
              l := 1,
              N := 32,
              n := 16,
              r := 1 ),
          instr := [ rec(
                  instr := vunpacklo_16x8i,
                  p := [  ] ), rec(
                  instr := vunpackhi_16x8i,
                  p := [  ] ) ],
          v := 16,
          vperm := VPerm(L(32, 16), (y, x) -> chain(assign(vref(y, 0, 16), vunpacklo_16x8i(vref(x, 0, 16), vref(x, 16, 16), [  ])), assign(vref(y, 16, 16), vunpackhi_16x8i(vref(x, 0, 16), vref(x, 16, 16), [  ]))), 16, 2) ), rec(
          perm := rec(
              spl := Tensor(
                  L(16, 8),
                  I(2)
                ),
              l := 1,
              N := 16,
              n := 8,
              r := 2 ),
          instr := [ rec(
                  instr := vunpacklo2_16x8i,
                  p := [  ] ), rec(
                  instr := vunpackhi2_16x8i,
                  p := [  ] ) ],
          v := 16,
          vperm := VPerm(Tensor(
                L(16, 8),
                I(2)
              ), (y, x) -> chain(assign(vref(y, 0, 16), vunpacklo2_16x8i(vref(x, 0, 16), vref(x, 16, 16), [  ])), assign(vref(y, 16, 16), vunpackhi2_16x8i(vref(x, 0, 16), vref(x, 16, 16), [  ]))), 16, 2) ), rec(
          perm := rec(
              spl := Tensor(
                  L(8, 4),
                  I(4)
                ),
              l := 1,
              N := 8,
              n := 4,
              r := 4 ),
          instr := [ rec(
                  instr := vunpacklo4_16x8i,
                  p := [  ] ), rec(
                  instr := vunpackhi4_16x8i,
                  p := [  ] ) ],
          v := 16,
          vperm := VPerm(Tensor(
                L(8, 4),
                I(4)
              ), (y, x) -> chain(assign(vref(y, 0, 16), vunpacklo4_16x8i(vref(x, 0, 16), vref(x, 16, 16), [  ])), assign(vref(y, 16, 16), vunpackhi4_16x8i(vref(x, 0, 16), vref(x, 16, 16), [  ]))), 16, 2) ), rec(
          perm := rec(
              spl := Tensor(
                  L(4, 2),
                  I(8)
                ),
              l := 1,
              N := 4,
              n := 2,
              r := 8 ),
          instr := [ rec(
                  instr := vunpacklo8_16x8i,
                  p := [  ] ), rec(
                  instr := vunpackhi8_16x8i,
                  p := [  ] ) ],
          v := 16,
          vperm := VPerm(Tensor(
                L(4, 2),
                I(8)
              ), (y, x) -> chain(assign(vref(y, 0, 16), vunpacklo8_16x8i(vref(x, 0, 16), vref(x, 16, 16), [  ])), assign(vref(y, 16, 16), vunpackhi8_16x8i(vref(x, 0, 16), vref(x, 16, 16), [  ]))), 16, 2) ), rec(
          perm := rec(
              spl := Tensor(
                  L(8, 2),
                  I(4)
                ),
              l := 1,
              N := 8,
              n := 2,
              r := 4 ),
          instr := [ rec(
                  instr := vshuffle4_16x8i,
                  p := [ 1, 3, 1, 3 ] ), rec(
                  instr := vshuffle4_16x8i,
                  p := [ 2, 4, 2, 4 ] ) ],
          v := 16,
          vperm := VPerm(Tensor(
                L(8, 2),
                I(4)
              ), (y, x) -> chain(assign(vref(y, 0, 16), vshuffle4_16x8i(vref(x, 0, 16), vref(x, 16, 16), [ 1, 3, 1, 3 ])), assign(vref(y, 16, 16), vshuffle4_16x8i(vref(x, 0, 16), vref(x, 16, 16), [ 2, 4, 2, 4 ]))), 16, 2) ), rec(
          perm := rec(
              spl := Tensor(
                  I(2),
                  L(4, 2),
                  I(4)
                ),
              l := 2,
              N := 4,
              n := 2,
              r := 4 ),
          instr := [ rec(
                  instr := vshuffle4_16x8i,
                  p := [ 1, 3, 1, 3 ] ), rec(
                  instr := vshuffle4_16x8i,
                  p := [ 2, 4, 2, 4 ] ) ],
          v := 16,
          vperm := VPerm(Tensor(
                L(4, 2),
                I(8)
              ), (y, x) -> chain(assign(vref(y, 0, 16), vunpacklo8_16x8i(vref(x, 0, 16), vref(x, 16, 16), [  ])), assign(vref(y, 16, 16), vunpackhi8_16x8i(vref(x, 0, 16), vref(x, 16, 16), [  ]))), 16, 2) *
            VPerm(Tensor(
                L(4, 2),
                I(8)
              ) *
              Tensor(
                I(2),
                L(4, 2),
                I(4)
              ), (y, x) -> chain(assign(vref(y, 0, 16), vshuffle4_16x8i(vref(x, 0, 16), vref(x, 16, 16), [ 1, 3, 1, 3 ])), assign(vref(y, 16, 16), vshuffle4_16x8i(vref(x, 0, 16), vref(x, 16, 16), [ 2, 4, 2, 4 ]))), 16, 4.2000000000000002) *
            VTensor(I(2), 16) ), rec(
          perm := rec(
              spl := Tensor(
                  I(2),
                  L(16, 8)
                ),
              l := 2,
              N := 16,
              n := 8,
              r := 1 ),
          instr := [ rec(
                  instr := vunpacklo_16x8i,
                  p := [  ] ), rec(
                  instr := vunpackhi_16x8i,
                  p := [  ] ) ],
          v := 16,
          vperm := VTensor(I(2), 16) *
            VPerm(Tensor(
                I(2),
                L(16, 8)
              ) *
              Tensor(
                L(4, 2),
                I(8)
              ), (y, x) -> chain(assign(vref(y, 0, 16), vunpacklo_16x8i(vref(x, 0, 16), vref(x, 16, 16), [  ])), assign(vref(y, 16, 16), vunpackhi_16x8i(vref(x, 0, 16), vref(x, 16, 16), [  ]))), 16, 4.2000000000000002) *
            VPerm(Tensor(
                L(4, 2),
                I(8)
              ), (y, x) -> chain(assign(vref(y, 0, 16), vunpacklo8_16x8i(vref(x, 0, 16), vref(x, 16, 16), [  ])), assign(vref(y, 16, 16), vunpackhi8_16x8i(vref(x, 0, 16), vref(x, 16, 16), [  ]))), 16, 2) ), rec(
          perm := rec(
              spl := Tensor(
                  I(2),
                  L(8, 4),
                  I(2)
                ),
              l := 2,
              N := 8,
              n := 4,
              r := 2 ),
          instr := [ rec(
                  instr := vunpacklo2_16x8i,
                  p := [  ] ), rec(
                  instr := vunpackhi2_16x8i,
                  p := [  ] ) ],
          v := 16,
          vperm := VTensor(I(2), 16) *
            VPerm(Tensor(
                I(2),
                L(8, 4),
                I(2)
              ) *
              Tensor(
                L(4, 2),
                I(8)
              ), (y, x) -> chain(assign(vref(y, 0, 16), vunpacklo2_16x8i(vref(x, 0, 16), vref(x, 16, 16), [  ])), assign(vref(y, 16, 16), vunpackhi2_16x8i(vref(x, 0, 16), vref(x, 16, 16), [  ]))), 16, 4.2000000000000002) *
            VPerm(Tensor(
                L(4, 2),
                I(8)
              ), (y, x) -> chain(assign(vref(y, 0, 16), vunpacklo8_16x8i(vref(x, 0, 16), vref(x, 16, 16), [  ])), assign(vref(y, 16, 16), vunpackhi8_16x8i(vref(x, 0, 16), vref(x, 16, 16), [  ]))), 16, 2) ), rec(
          perm := rec(
              spl := Tensor(
                  I(2),
                  L(4, 2),
                  I(4)
                ),
              l := 2,
              N := 4,
              n := 2,
              r := 4 ),
          instr := [ rec(
                  instr := vunpacklo4_16x8i,
                  p := [  ] ), rec(
                  instr := vunpackhi4_16x8i,
                  p := [  ] ) ],
          v := 16,
          vperm := VTensor(I(2), 16) *
            VPerm(Tensor(
                I(2),
                L(4, 2),
                I(4)
              ) *
              Tensor(
                L(4, 2),
                I(8)
              ), (y, x) -> chain(assign(vref(y, 0, 16), vunpacklo4_16x8i(vref(x, 0, 16), vref(x, 16, 16), [  ])), assign(vref(y, 16, 16), vunpackhi4_16x8i(vref(x, 0, 16), vref(x, 16, 16), [  ]))), 16, 4.2000000000000002) *
            VPerm(Tensor(
                L(4, 2),
                I(8)
              ), (y, x) -> chain(assign(vref(y, 0, 16), vunpacklo8_16x8i(vref(x, 0, 16), vref(x, 16, 16), [  ])), assign(vref(y, 16, 16), vunpackhi8_16x8i(vref(x, 0, 16), vref(x, 16, 16), [  ]))), 16, 2) ) ],
  unrules := [ rec(
          perm := rec(
              spl := Tensor(
                  L(4, 2),
                  I(4)
                ),
              l := 1,
              N := 4,
              n := 2,
              r := 4 ),
          instr := rec(
              instr := vushuffle4_16x8i,
              p := [ 1, 3, 2, 4 ] ),
          v := 16,
          vperm := VPerm(Tensor(
                L(4, 2),
                I(4)
              ), (y, x) -> assign(vref(y, 0, 16), vushuffle4_16x8i(vref(x, 0, 16), [ 1, 3, 2, 4 ])), 16, 0.90000000000000002) ), rec(
          perm := rec(
              spl := Tensor(
                  I(2),
                  L(4, 2),
                  I(2)
                ),
              l := 2,
              N := 4,
              n := 2,
              r := 2 ),
          instr := [ rec(
                  instr := vushufflelo2_16x8i,
                  p := [ 1, 3, 2, 4 ] ), rec(
                  instr := vushufflehi2_16x8i,
                  p := [ 1, 3, 2, 4 ] ) ],
          v := 16,
          vperm := VPerm(Tensor(
                I(2),
                L(4, 2),
                I(2)
              ), (y, x) -> Let(t => TempVec(TArray(x.t.t, Eval(v))),
               decl(t, chain(assign(vref(t, 0, Eval(v)), Eval(i1)(vref(x, 0, Eval(v)), Eval(op1.p))), assign(vref(y, 0, Eval(v)), Eval(i2)(vref(t, 0, Eval(v)), Eval(op2.p))))) )
             , 16, 1.8) ) ],
  x_I_vby2 := [ [ rec(
              instr := vunpacklo8_16x8i,
              p := [  ] ), rec(
              instr := vshuffle4_16x8i,
              p := [ 1, 2, 3, 4 ] ) ], [ rec(
              instr := vshuffle4_16x8i,
              p := [ 3, 4, 1, 2 ] ), rec(
              instr := vunpackhi8_16x8i,
              p := [  ] ) ] ] ));


text:
# TODO: Really we should be formatting text and HTML output
#       And the HTML output could for instance link to the
#       documentation of the attributes
BindGlobal("JUPYTER_FormatKnown",
function(obj)
    local res, n, p, props, attrs, len;

    props := KnownPropertiesOfObject(obj);
    attrs := KnownAttributesOfObject(obj);

    len   := Maximum(List(props, Length));
    len   := Maximum(len, Maximum(List(props, Length))) + 1;

    res := "Properties:\n\n";
    props := List(props,
                  x -> STRINGIFY(String(x, -len), ": ",
                                 ValueGlobal(x)(obj)));
    Append(res, JoinStringsWithSeparator(props, "\n"));

    Append(res, "\n\nAttributes:\n\n");
    attrs := List(attrs,
                  x -> STRINGIFY(String(x, -len), ": ",
                                 ValueGlobal(x)(obj)));
    Append(res, JoinStringsWithSeparator(attrs, "\n"));
    return res;
end);

BindGlobal("JUPYTER_FindHelp",
function(ident)
    local s, matches, match, book, data, data1, lines, info;

    s := SIMPLE_STRING(ident);
    matches := HELP_GET_MATCHES(HELP_KNOWN_BOOKS[1], s, true);
    if matches[1] <> [] then
        match := matches[1][1];
    elif matches[2] <> [] then
        match := matches[2][1];
    else
        return "Undocumented";
    fi;
    book := match[1];
    info := HELP_BOOK_INFO(match[1]);

    data := HELP_BOOK_HANDLER.GapDocGAP.HelpData(info, match[2], "text");
    data1 := HELP_BOOK_HANDLER.GapDocGAP.HelpData(info, match[2] + 1, "text");

    if IsString(data.lines) then
        lines := SplitString(data.lines, "\n");
    else
        lines := data.lines;
    fi;
    return JoinStringsWithSeparator(lines{[data.start..data1.start-1]}, "\n");
end);

InstallGlobalFunction(JUPYTER_Inspect,
function(str, pos)
    local cpos, ipos, ident, ws, sep, fapp, result, found,
          var, textplain, texthtml;

    found := false;
    textplain := "";
    texthtml := "";

    # extract keyword/identifier
    # go to the left of pos
    # TODO: This should really use a GAP Parser or the
    #       SYNTAX_TREE module; SYNTAX_TREE doesn't have position
    #       information
    # Once we can parse code partially, we could even try to evaluate
    # subexpressions for help tips?

    # ( is not a separator, because we use it to
    # detect function application
    sep := [") \t\n\r;:=<>=!."];

    cpos := Minimum(pos, Length(str));
    ipos := 1;
    fapp := false;
    ident := [];

    # skip whitespace
    while cpos > 0 and (str[cpos] in " \t") do cpos := cpos - 1; od;
    while cpos > 0 and (not str[cpos] in sep) do
        if str[cpos] = '(' then
            fapp := true;
        else
            ident[ipos] := str[cpos];
            ipos := ipos + 1;
        fi;
        cpos := cpos - 1;
    od;
    ident := Reversed(ident);

    if ident <> "" then
        found := true;
        if fapp then
            # find documentation for function application
            textplain := JUPYTER_FindHelp(ident{[1..Length(ident)-1]});
        elif IsBoundGlobal(ident) then
            var := ValueGlobal(ident);
            if IsFunction(var) then
                # try finding doc?
                textplain := JUPYTER_FindHelp(ident);
            elif
                IsObject(var) then
                # Display Known Properties/Attributes/Categories/Types
                textplain := JUPYTER_FormatKnown(var);
            fi;
        fi;
    fi;
    return rec( status := "ok",
                found := found,
                data := rec( text\/html := texthtml,
                             text\/plain := textplain,
                             metadata := rec( text\/html := "",
                                              text\/plain := "" ) ) );
end);

max_stars_repo_name: ZachNewbery/JupyterKernel

max_issues_repo_name: ZachNewbery/JupyterKernel

max_forks_repo_name: ZachNewbery/JupyterKernel


text:
InstallGlobalFunction(MEMO_MongoDBCache,
function(memo, path)
  local url, cache, type;

  # Full URL including function name
  url := path;
  if not EndsWith(url, "/") then
    Add(url, '/');
  fi;
  Append(url, memo!.funcname);

  # Make cache object
  cache := rec(memo := memo,  # memoised function
               url := url);  # URL of the database
  # Objectify
  type := NewType(DictionariesFamily, MEMO_IsMongoDBCache);
  cache := Objectify(type, cache);

  return cache;
end);

InstallMethod(AddDictionary,
"for a memoisation disk cache and two objects",
[MEMO_IsMongoDBCache, IsObject, IsObject],
function(cache, key, val)
  local memo, h, storedkey, query, namespace, result, args, post_string, url,
        db_response, res;
  memo := cache!.memo;

  # Get hash
  h := memo!.hash(key);

  # Construct MongoDB query as record
  query := rec(hash := h,
               namespace := MEMO_MongoDBNamespace,
               result := memo!.pickle(val));

  # OPTION: storekey
  if memo!.storekey then
    query.key := memo!.pickle(key);
  fi;

  # OPTION: metadata
  if memo!.metadata <> fail then
    query.metadata := memo!.metadata();
  fi;

  # Query the server
  args := List(RecNames(query), rnam -> Concatenation(rnam, "=", query.(rnam)));
  post_string := JoinStringsWithSeparator(args, "&");
  url := cache!.url;
  Info(InfoMemoisation, 3, "Posting to ", url);
  Info(InfoMemoisation, 4, "(including ",
       JoinStringsWithSeparator(RecNames(query), ", "), ")");
  db_response := PostToURL(cache!.url, post_string);
  if db_response.success = false then
    # No valid response from server
    Error("AddDictionary (MongoDB cache): ", db_response.error);
  fi;
  res := JsonStringToGap(db_response.result);

  if res._status = "ERR" then
    # Problem with database
    Error("AddDictionary (MongoDB cache): ", res);
  elif res._status = "OK" then
    # Success
    return;
  fi;
  Error("AddDictionary (MongoDB cache): ",
        "<res>._status should be \"ERR\" or \"OK\"");

  # no return value
end);

InstallMethod(KnowsDictionary,
"for a memoisation disk cache and an object",
[MEMO_IsMongoDBCache, IsObject],
function(cache, key)
  local item;
  item := MEMO_MongoDBQuery(cache, key);
  return item <> fail;
end);

InstallMethod(LookupDictionary,
"for a memoisation disk cache and an object",
[MEMO_IsMongoDBCache, IsObject],
function(cache, key)
  local memo, item, storedkey;
  memo := cache!.memo;

  # Request item from database
  item := MEMO_MongoDBQuery(cache, key);
  if item = fail then
    # We shouldn't normally get here, as we usually check KnowsDictionary first
    Info(InfoMemoisation, 1, "No entry found in database");
    return fail;
  fi;

  # OPTION: storekey
  if memo!.storekey then
    storedkey := memo!.unpickle(item.key);
    # check if key still matches
    if key <> storedkey then
      ErrorNoReturn("Hash collision: <key> does not match <storedkey>");
    fi;
    Info(InfoMemoisation, 3, "Key matches that stored on the server");
  fi;

  # OPTION: unhash
  if memo!.unhash <> fail then
    # unhash and check if key still matches
    storedkey := memo!.unhash(item.hash);
    if storedkey <> key then
      ErrorNoReturn("Hash collision: <key> does not match <storedkey>");
    fi;
  fi;

  return memo!.unpickle(item.result);
end);

InstallMethod(MEMO_ClearCache,
"for a memoisation disk cache",
[MEMO_IsMongoDBCache],
function(cache)
  local db_response;
  db_response := DeleteURL(cache!.url);
  if db_response.success <> true then
    Error("MongoDB cache: failed to clear");
  fi;
  return db_response.success;
end);

InstallGlobalFunction(MEMO_MongoDBQuery,
function(cache, key)
  local memo, query, url, db_response, item;
  memo := cache!.memo;

  # Construct the arguments
  query := rec(namespace := MEMO_MongoDBNamespace);
  query := List(RecNames(query), rnam -> Concatenation("%22",
                                                      rnam,
                                                      "%22=%22",
                                                      query.(rnam),
                                                      "%22"));
  query := JoinStringsWithSeparator(query, ",");
  url := Concatenation(cache!.url, "/", memo!.hash(key),
                       "?where={", query, "}");
  Info(InfoMemoisation, 4, "Querying ", url);
  db_response := DownloadURL(url);
  if db_response.success = false then
    # No valid response from server
    Error("MongoDB cache: ", db_response.error);
  fi;
  item := JsonStringToGap(db_response.result);
  if IsBound(item._status) and item._status = "ERR" then
    if item._error.code = 404 then
      # No result for this hash on server (no problem!)
      return fail;
    else
      # Something else went wrong
      Error("MongoDB cache: ", item._error.code, " ", item._error.message);
    fi;
  fi;

  # Return a single item as a record
  return item;
end);

max_stars_repo_name: gap-packages/Memoisation

max_issues_repo_name: gap-packages/Memoisation

max_forks_repo_name: gap-packages/Memoisation


text:
# Copyright (c) 2018-2021, Carnegie Mellon University
# See LICENSE for details

# ================================================================
# Simplification of Intervals
# ================================================================

full_II := (int, size) ->
    [int.target(II), size, 0, @.cond(e->e=size.val)];

empty_II := (int, size) ->
    [int.target(II).cond(e->e.params[2]=e.params[3]), size, @, @];

left_II := (int, size, endd) ->
    [int.target(II), size, 0, endd];

right_II := (int, size,start) ->
    [int.target(II), size, start, @.cond(e->e=size.val)];

Class(RulesII, RuleSet);

RewriteRules(RulesII, rec(
    # full II o index mapping func @(3) = II with domain of @(3)
    # II(n, 0, n) o f = II(domain(f), 0, domain(f))
    FullII_f := ARule(fCompose, [ full_II(@, @(1)), @(2) ],  e -> [ II(@(2).val.domain()) ]),
    EmptyII_f := ARule(fCompose, [ empty_II(@, @(1)), @(2) ],  e -> [ II(@(2).val.domain(),0,0) ]),

    # partial II o dirsum of perms
    # II(n, 0, k) o fDirsum(perm_k, perm_?) -> II(n,0,k)
    LeftII_fDirsum := ARule(fCompose,
        [ left_II(@(0), @(1), @(2)), [fDirsum, @(3).cond(e -> is_perm(e) and e.range()=@(2).val), ...]],
        e -> [ @(0).val ]),

    # partial II o dirsum of perms
    # II(n, n-k, n) o fDirsum(perm_?, perm_k) -> II(n,n-k,n)
    RightII_fDirsum := ARule( fCompose,
        [ right_II(@(0), @(1), @(2)), [fDirsum, ..., @(4).cond(e -> is_perm(e) and e.range() = @(1).val-@(2).val)]],
        e -> [ @(0).val ]),

    # fTensor(IIn, IIk) -> II(n*k)
    fullII_tensor_fullII := ARule(diagTensor, [full_II(@(0), @(1)), full_II(@(0), @(2))],
        e -> [ II(@(1).val * @(2).val) ]),

    # fDirsum(IIn, IIk) -> II(n+k)
    fullII_dirsum_fullII := ARule(diagDirsum, [full_II(@(0), @(1)), full_II(@(0), @(2))],
        e -> [ II(@(1).val + @(2).val) ]),

    diagTensor_emptyII := Rule([diagTensor, ..., empty_II(@(1), @(2)), ...], e -> II(e.domain(),0,0)),
    diagTensor_fullII_Id1 := ARule(diagTensor, [@(0), full_II(@(1), @(2).cond(e->e=1))], e -> [ @(0).val ]),
    diagTensor_fullII_Id2 := ARule(diagTensor, [full_II(@(1), @(2).cond(e->e=1)), @(0)], e -> [ @(0).val ]),

    II_dirsum_emptyII := ARule(diagDirsum, [[II, @(1), @(2), @(3)], empty_II(@(4), @(5))],
        e -> [ II(@(1).val + @(5).val), @(2).val, @(3).val ]),

    emptyII_dirsum_II := ARule(diagDirsum, [empty_II(@(4), @(5)), [II, @(1), @(2), @(3)]],
        e -> [ II(@(1).val + @(5).val), @(5).val + @(2).val, @(5).val + @(3).val ]),

    # II Shifting, we support shift left (shift <= start), and right (shift >= end)
    # II o Z = shifted II#
    II_Z := ARule(fCompose, [[II, @(1), @(2), @(3)], [Z, @(4), @(5).cond(e -> (e<=@(2).val) or (e >= @(3).val))]],
        e -> [II(@(1).val, (@(2).val-@(5).val) mod @(1).val,
               # this makes 0->size, because size mod size = 0
                let(last:=(@(3).val-@(5).val) mod @(1).val,
                    When(last=0, @(1).val, last))) ]),

    DiagFullII_toId := Rule([Diag, full_II(@(1), @(2))], e -> I(@(2).val)),
    Diag_fConst_toId := Rule([Diag, [fConst, @(2), @(1), 1]], e -> I(@(1).val)),
    Diag_fConstV_toId := Rule([Diag, [fConst, @(2), @(1), _1]], e -> I(@(1).val)),

    COND_fullII := Rule([COND, full_II(@(1), @(2)), @(3), @(4)], e -> @(3).val),
    COND_emptyII := Rule([COND, full_II(@(1), @(2)), @(3), @(4)], e -> @(4).val)
));


text:
# Copyright 2018-2019, Carnegie Mellon University
# See LICENSE for details

Class(FloatMixin, rec(
    XType := TPtr(T_Real(32)), precision := "single", TRealCtype := "float")
);

Class(DoubleMixin, rec(
    XType := TPtr(T_Real(64)), precision := "double", TRealCtype := "double")
);

Class(CoSynthesizeStrategies, rec(
    C_opt := [ (t, opts) -> RandomRuleTree(t, opts),
        (rt, opts) -> SPLRuleTree(rt),
        (s, opts) -> SumsSPL(s, opts),
        (s, opts) -> Rewrite(s, [RulesSumsHCOL, RulesTerminateReductionHCOL, RulesSumsHCOL], opts),
        (s, opts) -> HCOLProof_Codegen(s, opts),
        (c, opts) -> Rewrite(c, RulesCodeUnrollHCOL, opts),
		(c, opts) -> Rewrite(c, RulesTypeHCOL, opts)		],
    C_opt_useAbsMax := [ (t, opts) -> RandomRuleTree(t, opts),
		(rt, opts) -> SPLRuleTree(rt),
		(s, opts) -> SumsSPL(s, opts),
		(s, opts) -> Rewrite(s, [RulesSumsHCOL], opts),
		(s, opts) -> Rewrite(s, [RulesSumsHCOL, RulesTerminateReductionHCOL, RulesSumsHCOL], opts),
		(s, opts) -> HCOLProof_Codegen(s, opts),
		(c, opts) -> Rewrite(c, RulesCodeUnrollHCOLuseAbsMaxSR, opts) ],
    C_raw := [ (t, opts) -> RandomRuleTree(t, opts),
        (rt, opts) -> SPLRuleTree(rt),
        (s, opts) -> SumsSPL(s, opts),
        (s, opts) -> Rewrite(s, [RulesSumsHCOL, RulesTerminateReductionHCOL, RulesSumsHCOL], opts),
        (s, opts) -> HCOLProof_Codegen(s, opts) ],
    C_sim := [        (s, opts) -> SumsSPL(s, opts),
        (s, opts) -> Rewrite(s, [RulesSumsHCOL, RulesTerminateReductionHCOL, RulesSumsHCOL], opts),
        (s, opts) -> HCOLProof_Codegen(s, opts),
	(c, opts) -> Rewrite(c, RulesCodeUnrollHCOL, opts) ],
	no_opt := [ (t, opts) -> RandomRuleTree(t, opts),
        (rt, opts) -> SPLRuleTree(rt),
        (s, opts) -> SumsSPL(s, opts),
        (s, opts) -> Rewrite(s, [RulesSumsHCOL, RulesTerminateReductionHCOL, RulesSumsHCOL], opts),
        (s, opts) -> HCOLProof_Codegen(s, opts) ]
));

Class(HCOLopts, rec(
    getOpts := meth(arg)
        local opts;

        opts := CopyFields(SpiralDefaults,
            rec(
                codegen := HCOLCodegen,
                sumsgen := HCOLSumsGen,
                params := [],
                includes := [],
                unparser := HCOLUnparser,
                operations := rec(Print := (s) -> Print("<HCOL options"::When(Length(arg)>1 and IsBound(arg[2].name), ", "::arg[2].name, "")::">")),
                funcgen := HCOLFuncGen,
                useCReturn := false,
				errorCheck := false,
                YType := TPtr(TInt),
                csStrategy := CoSynthesizeStrategies.C_opt
            ),
            When(Length(arg)=2, arg[2]));
        return opts;
    end
));

max_stars_repo_name: spiral-software/spiral-package-hcol

max_issues_repo_name: spiral-software/spiral-package-hcol

max_forks_repo_name: spiral-software/spiral-package-hcol


text:
n := 10;
for i in [1 .. n] do
    Print(i);
    if i < n then
        Print(", ");
    else
        Print("\n");
    fi;
od;

ext: gap

max_issues_repo_name: seanwallawalla-forks/RosettaCodeData

max_forks_repo_name: seanwallawalla-forks/RosettaCodeData


text:
Read( "merge_sort.gi" );

list := List( [ 1 .. 100 ], i -> Random( [ 1 .. 50 ] ) );

list := merge_sort( list );

IsSortedList( list );


text:
##  Copyright (c) 2018-2021, Carnegie Mellon University
##  See LICENSE for details

Class(HockneyOpts, FFTXConvOpts, rec(
    tags := [],
    operations := rec(Print := s -> Print("<FFTX Hockney options record>"))
));

hockneyOpts := function(arg)
    local opts, maxSize, argrec;
    opts := Copy(FFTXConvOpts);

    argrec := rec(
        globalUnrolling := opts.globalUnrolling,
        prunedBasemaxSize := opts.globalUnrolling / 2
    );

    if IsBound(arg[1].args) and Length(arg[1].args) >= 2 and IsRec(arg[1].args[2]) then
           argrec := CopyFields(argrec, arg[1].args[2]);
    fi;
    opts.globalUnrolling := argrec.globalUnrolling;

    opts.useDeref := false;
    opts.breakdownRules.PRDFT := List([ PRDFT1_Base2, PRDFT1_CT, PRDFT_PD], _noT);
    opts.breakdownRules.IPRDFT := List([ IPRDFT1_Base1, IPRDFT1_Base2, IPRDFT1_CT, IPRDFT_PD], _noT);
    opts.breakdownRules.IPRDFT2 := List([ IPRDFT2_Base1, IPRDFT2_Base2, IPRDFT2_CT], _noT);
    opts.breakdownRules.PRDFT3 := List([ PRDFT3_Base1, PRDFT3_Base2, PRDFT3_CT, PRDFT3_OddToPRDFT1], _noT);
    opts.breakdownRules.URDFT := List([ URDFT1_Base1, URDFT1_Base2, URDFT1_Base4, URDFT1_CT ], _noT);
    opts.breakdownRules.DFT := [DFT_Base, DFT_PD, DFT_CT];
    opts.breakdownRules.IOPrunedMDRConv := [IOPrunedMDRConv_3D_2trip_zyx_freqdata];
    opts.breakdownRules.MDDFT := [ MDDFT_Base, MDDFT_RowCol ];
    opts.breakdownRules.GT := [ GT_NthLoop ];
    opts.breakdownRules.DFT := [ DFT_Base, DFT_CT, DFT_Rader, CopyFields(DFT_GoodThomas, rec(maxSize := 15)), DFT_PD ];
    opts.topTransforms := [DFT, MDDFT, PrunedDFT, PrunedIDFT, IOPrunedConv, PrunedPRDFT, PrunedIPRDFT, TTensorI, IOPrunedMDRConv,
        PRDFT, IPRDFT, PRDFT1, IPRDFT1, PRDFT2, IPRDFT2, PRDFT3, IPRDFT3, TTensorI ];
    opts.breakdownRules.MDRConv := [ MDRConv_3D_2trip_zyx_freqdata ]; # [MDRConv_Base]

    opts.breakdownRules.PrunedPRDFT := [ CopyFields(PrunedPRDFT_base, rec(maxSize := argrec.prunedBasemaxSize)), PrunedPRDFT_CT_rec_block ];
    opts.breakdownRules.PrunedIPRDFT := [ CopyFields(PrunedIPRDFT_base, rec(maxSize := argrec.prunedBasemaxSize)), PrunedIPRDFT_CT_rec_block ];
    opts.breakdownRules.PrunedDFT := [ CopyFields(PrunedDFT_base, rec(maxSize := argrec.prunedBasemaxSize)), PrunedDFT_CT_rec_block ];

    return opts;
end;

hockneyConf := rec(
    defaultName := "defaultHockneyConf",
    defaultOpts := (arg) >> rec(useHockney := true, args := arg),
    confHandler := hockneyOpts
);

fftx.FFTXGlobals.registerConf(hockneyConf);

max_stars_repo_name: franzfranchetti/spiral-package-fftx

max_issues_repo_name: franzfranchetti/spiral-package-fftx

max_forks_repo_name: franzfranchetti/spiral-package-fftx


text:
local reps,tori,labels,I,II,ords;

# Permutation from standard to gap
# / 1 2 3 4 \
# \ 2 4 3 1 /
# Position(pr,Permuted([2,3,4,2],(2,4,1)))=24;

#......Ross Jordan Block Sizes........Donna & Ross nilpotents........(in GAP notation)
reps:=[[[2,1],[4,1],[3,1],[1,1]],    # F_4
       [[2,1],[4,1],[7,1],[5,1]],    # F_4(a_1) [[2,1],[4,1],[10,1],[1,1]],
       [[6,1],[10,1],[1,1],[5,1]],   # F_4(a_2) [[9,1],[1,1],[10,1],[4,1]],
       [[4,1],[3,1],[1,1]],          # C_3      [[1,1],[3,1],[4,1]],
       [[2,1],[4,1],[3,1]],          # B_3      the same
       [[4,1],[6,1],[10,1],[18,1]],  # F_4(a_3) [[4,1],[13,1],[11,1],[12,1]],
       [[4,1],[1,1],[10,1]],         # C_3(a_1) [[1,1],[10,1],[4,1]],
       [[2,1],[3,1],[1,1]],          # sA_2A_1  [[3,1],[1,1],[2,1]],
       [[4,1],[3,1]],                # B_2      the same
       [[2,1],[4,1],[1,1]],          # A_2sA_1  the same
       [[3,1],[1,1]],                # sA_2     the same
       [[2,1],[4,1]],                # A_2      the same
       [[2,1],[3,1]],                # A_1sA_1  [[2,1],[1,1]],
       [[3,1]],                      # sA_1     [[1,1]],
       [[2,1]]];                     # A_1      [[2,1]]

I:=[[],[3],[2,3],[],[],[2,3,1],[3],[],[],[],[],[],[],[],[]];

#
# The parabolic where the representative is distinguished
#
II:=[[1,2,3,4],
     [1,2,3,4],
     [1,2,3,4],
     [4,3,1],
     [2,4,3],
     [1,2,3,4],
     [4,3,1],
     [3,1,2],
     [4,3],
     [2,4,1],
     [3,1],
     [2,4],
     [2,1],
     [1],
     [2]];

labels:=["F_4","F_4(a_1)","F_4(a_2)","C_3","B_3","F_4(a_3)","C_3(a_1)","\\tilde A_2A_1","B_2","A_2\\tilde A_1","\\tilde A_2","A_2","A_1\\tilde A_1","\\tilde A_1","A_1"];

tori:=[
       [2,2,2,2],
       [2,2,0,2],
       [2,0,0,2],
       [2,1,1,0],
       [0,2,0,2],
       [0,0,0,2],
       [0,1,1,0],
       [1,0,0,1],
       [1,2,0,0],
       [0,0,1,0],
       [2,0,0,0],
       [0,2,0,0],
       [0,0,0,1],
       [1,0,0,0],
       [0,1,0,0]
    ];

ords:=[];

return [reps,tori,labels,I,II,ords];


text:
##  Copyright (c) 2018-2021, Carnegie Mellon University
##  See LICENSE for details

FixUpHIP_Code := function (c, opts)
    local kernels, kernel_inits, globals, var_decls, var_dels, cx, v, dptr;

    if IsBound(opts.fixUpTeslaV_Code) and opts.fixUpTeslaV_Code then
        kernels := List(Collect(c, specifiers_func), k->k.id);

        dptr := var.fresh_t("hp", TPtr(TReal));

        kernel_inits := List(kernels, k-> call(rec(id := "hipFuncSetCacheConfig"), fcall("reinterpret_cast<const void*>", k), "hipFuncCachePreferL1"));

        globals := Flat(List(Collect(c, @@(1, decl, (e, cx) -> (not IsBound(cx.specifiers_func) or cx.specifiers_func = []) and
                               (not IsBound(cx.func) or cx.func = []))), x->x.vars));

        var_decls := chain(Flat(List(globals, v -> [
                call(rec(id := "hipMalloc"), tcast(TPtr(TPtr(TVoid)), addrof(dptr)), sizeof(v.t.t) * v.t.size),
                call(rec(id := "hipMemcpyToSymbol"), fcall("HIP_SYMBOL", v), addrof(dptr), sizeof(dptr.t))
            ])));

        var_dels := decl(dptr, chain(Flat(List(globals, v -> [
                call(rec(id := "hipMemcpyFromSymbol"), addrof(dptr), fcall("HIP_SYMBOL", v), sizeof(dptr.t)),
                call(rec(id := "hipFree"), dptr)
            ]))));

        cx := chain(kernel_inits :: [var_decls]);
        for v in globals do
            v.t := TPtr(v.t.t, ["__device__"]);
        od;

        c := SubstBottomUp(c, @(1, func, f -> f.id = "init"),
            e -> CopyFields(@(1).val, rec(cmd := decl(dptr, chain(cx, @(1).val.cmd))))
        );
        c := SubstBottomUp(c, @(1, func, f -> f.id = "destroy"),
            e -> CopyFields(@(1).val, rec(cmd := chain(var_dels, @(1).val.cmd)))
        );
        c := SubstBottomUp(c, @(1, chain, e -> ForAny(e.cmds, e -> ObjId(e) = func and e.id = "init")),
            e -> chain(Filtered(@(1).val.cmds, e-> ObjId(e) <> func or e.id <> "init") :: Filtered(@(1).val.cmds, e -> ObjId(e) = func and e.id = "init"))
        );

    fi;

    return c;
end;

max_stars_repo_name: mikefranusich/spiral-package-fftx

max_issues_repo_name: mikefranusich/spiral-package-fftx

max_forks_repo_name: mikefranusich/spiral-package-fftx