text:
# Takes two groups, and builds the pregroup underlying the free product of
# these two groups
#
# don't try using this on large groups.
#
InstallMethod(PregroupOfFreeProduct, "for two finite groups",
              [IsGroup and IsFinite, IsGroup and IsFinite],
function(G, H)
    local i, j, size, table, eltn;

    size := Size(G) + Size(H) - 1;
    table := NullMat(size,size);

    table{[2..Size(G)]}{[2..Size(G)]} := MultiplicationTable(G){[2..Size(G)]}{[2..Size(G)]};
    table{[Size(G)+1..size]}{[Size(G)+1..size]} := Size(G) - 1 + MultiplicationTable(H){[2..Size(H)]}{[2..Size(H)]};

    for i in [Size(G) + 1 .. size ] do
        for j in [Size(G) + 1 .. size ] do
            if table[i][j] = Size(G) then
                table[i][j] := 1;
            fi;
        od;
    od;

    for i in [1..size] do
        table[1][i] := i;
        table[i][1] := i;
    od;

    eltn := List([1..size], String);
    return PregroupByTable(eltn, table);
end);

# Pregroup of free product of entered groups
InstallGlobalFunction(PregroupOfFreeProductList,
function(l)
    local r;

    r.groups := l;

    return Objectify(PregroupOfFreeProductType, r);
end);

InstallMethod(PregroupByRedRelators,
              "for a free group, and a list of words of length 3",
              [ IsFreeGroup, IsList, IsList ],
function(F, rred, inv)
    local rkF, n, enams, table, i, j, r, pg, convert, ic;

    rkF := Length(GeneratorsOfGroup(F));

    if ForAny(rred, x -> not ( (x in F) and ( Length(x) = 3 ) ) ) then
        Error("rred has to be a list of words of length 3 over F");
    fi;

    ic := Length(inv);
    n := 1 + 2 * rkF;
    enams := Concatenation(["1"]
                          , Concatenation( List([1..rkF],
                                 x -> [ Concatenation("x", String(x))
                                      , Concatenation("X", String(x)) ] )));
    table := NullMat(n, n);

    # Multiplication by 1
    for i in [1..n] do
        table[1,i] := i;
        table[i,1] := i;
    od;

    # Multiplication of mutual inverse generators in
    # Free group
    for i in [2, 4..2 * rkF] do
        table[i, i+1] := 1;
        table[i+1, i] := 1;
    od;

    for i in inv do
        table[ 2*i, 2*i] := 1;
        table[ 2*i, 2*i + 1] := 0;
        table[ 2*i + 1, 2*i] := 0;
        table[ 2*i+1 , 2*i+1] := 1;

    od;

    convert := function(x)
        if x > 0 then
            return 2 * x;
        else
            # involution
            if -x in inv then
                return 2 * (-x);
            else
                return 2 * (-x) + 1;
            fi;
        fi;
    end;

    # Enter red relators
    # for r = x * y * z we get
    # - x * y = z^-1
    # - x = z^-1 * y^-1
    # - y * z = x ^ -1
    # - z = y^-1 * x^-1
    # - y = x^-1 * z^-1
    # - y^-1 = z * x
    for r in List(rred, LetterRepAssocWord) do
        table[ convert(r[1]), convert(r[2]) ] := convert(-r[3]);
        table[ convert(-r[3]), convert(-r[2]) ] := convert(r[1]);
        table[ convert(r[2]), convert(r[3]) ] := convert(-r[1]);
        table[ convert(-r[2]), convert(-r[1]) ] := convert(r[3]);
        table[ convert(-r[1]), convert(-r[3]) ] := convert(r[2]);
        table[ convert(r[3]), convert(r[1]) ] := convert(-r[2]);
    od;
    pg := PregroupByTable(enams, table);
    pg!.freegroup := F;
    pg!.convert_word := w -> List(LetterRepAssocWord(w), l -> pg[convert(l)]);
    return pg;
end);

max_stars_repo_name: RussWoodroofe/walrus

max_issues_repo_name: RussWoodroofe/walrus

max_forks_repo_name: RussWoodroofe/walrus


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

# ==========================================================================
# RowTensor
# ==========================================================================
Class(RowTensor, BaseOverlap, rec(
    #-----------------------------------------------------------------------
    dims := self >> let(D := self._children[1].dimensions,
        [ self.isize * D[1],
	  D[2] + AbsInt((D[2] - self.overlap) * (self.isize - 1)) ]),
    #-----------------------------------------------------------------------
    toAMat := self >> let(n := EvalScalar(self.isize),
        TensorProductAMat(AMatSPL(I(n)), AMatSPL(self._children[1])) *
	AMatSPL(Sparse(
		self._rowoverlap(
		    List([1..n], i-> EvalScalar(Cols(self._children[1]))),
		    EvalScalar(self.overlap)
		)))
    ),
    #-----------------------------------------------------------------------
    arithmeticCost := (self, costMul, costAddMul) >>
        self.isize * self._children[1].arithmeticCost(costMul, costAddMul)
));

# ==========================================================================
# ColTensor
# ==========================================================================
Class(ColTensor, BaseOverlap, rec(
    #-----------------------------------------------------------------------
    dims := self >> let(D := self._children[1].dimensions,
        [ D[1] + AbsInt((D[1] - self.overlap) * (self.isize - 1)),
	  self.isize * D[2] ]),
    #-----------------------------------------------------------------------
    toAMat := self >> let(n := _unwrap(self.isize),
        AMatSPL(Sparse(
		self._coloverlap(
		    List([1..n], i->self._children[1].dimensions[1]),
		    self.overlap
		))) *
	TensorProductAMat(AMatSPL(I(n)), AMatSPL(self._children[1]))
    )
));

ColTensor._transpose_class := RowTensor;
RowTensor._transpose_class := ColTensor;

ext: gi


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

_ToDec := v -> let(d:=Length(v), Sum(List([1..d], e -> v[e]*2^(d-e))));
_ToBin := (i,d) -> List([1..d], e -> BinAnd(QuoInt(i, 2^(d-e)), 1));

_TB := (i, n) -> GF(2).one * _ToBin(i, n);
_TD := (i) -> _ToDec(IntVecFFE(i));

PrintHex := function(lst, del)
    local i;
    if Length(lst) = 0 then
        return;
    fi;
    Print(HexInt(lst[1]));
    for i in [2..Length(lst)] do
        Print(del, HexInt(lst[i]));
    od;
end;

Declare(B);
Class(B, PermClass, rec(
    def := (n,l) -> Checked(
        # make sure the 1s are inside the matrix.
        ForAll(l, e ->
            IsPosInt(e[1]) and IsPosInt(e[2])
            and e[1] <= Log2Int(n) and e[2] <= Log2Int(n)),
        # make sure 'l' is a list.
        IsList(l),
	# done
	rec()),

    domain := self >> self.params[1],
    range  := self >> self.params[1],

    # return the bit matrix
    bm := meth(self)
        local n, m, i;

        n := Log2Int(self.params[1]);

        # generate matrix of zeros.
        m := List([1..n], e -> List([1..n], ee -> 0));

        # fill in identity
        for i in [1..n] do
            m[i][i] := 1;
        od;

        # xor in individual 1s from 'l'
        for i in self.params[2] do
            m[i[1]][i[2]] := BinXor(m[i[1]][i[2]], 1);
        od;

        return m * GF(2).root;
    end,

    # convert the sparse bit matrix info into a permutation matrix
    toAMat := meth(self)
        local m, n, i, M;

        m := self.bm();
        n := self.params[1];

        # generate full permutation matrix
        M := [];
        for i in [0..(n-1)] do
            Add(M, BasisVec(
                n,
                _TD(m * _TB(i, Log2Int(n)))
            ));
        od;

        return AMatMat(M);
    end,

    transpose := (self) >> self(
        self.params[1],
        self._mklist(
            MatAMat(
                InverseAMat(
                    AMatMat(self.bm())
                )
            )
        )
    ),

    _mklist := function(b)
        local l, i, j;

        Constraint(Dimensions(b)[1] = Dimensions(b)[2]);

        b := b - MatSPL(I(Dimensions(b)[1])) * GF(2).root;

        l := [];
        for i in [1..Length(b)] do
            for j in [1..Length(b)] do
                if b[i][j] = GF(2).root then
                    Add(l, [i,j]);
                fi;
            od;
        od;

        return l;
    end,

    transpose := self >> B(self.params[1], List(self.params[2], e -> [e[2],e[1]])),

    sums := (self) >> Chain(Error("Don't use legacy sumsgen!!"), true),
));

Declare(B2);

Class(B2, PermClass, rec(
    def := (N, E, S) -> Checked(
            Is2Power(N),
            Is2Power(E),
            Is2Power(S),
            E*(S^2) >= N,
            rec( transposed := false)
    ),

    domain := self >> self.params[1],
    range  := self >> self.params[1],

    transpose := self >> CopyFields(
        ApplyFunc(B2, self.params), rec(transposed := not self.transposed)),

    getES := (self) >> Product(self.params{[2..3]}),

    bm := meth(self)
        local n, nes, b, i;

        n := Log2Int(self.params[1]);
        nes := n - Log2Int(self.params[2] * self.params[3]);

        b := MatSPL(I(n)) * GF(2).root;

        if self.transposed then
            for i in [1..nes] do
                b[i+nes][i] := GF(2).root;
            od;
        else
            for i in [1..nes] do
                b[i][i+nes] := GF(2).root;
            od;
        fi;

        return b * GF(2).root;
    end,

    toAMat := meth(self)
        local b, n, i, M;

        b := self.bm();
        n := self.params[1];

        # generate full permutation matrix
        M := [];
        for i in [0..(n-1)] do
            Add(M, BasisVec(
                n,
                _TD(_TB(i, Log2Int(n)) * b)
            ));
        od;

        return AMatMat(M);
    end,
));

Declare(BP);

BPI := (n) -> BP(MatSPL(I(Log2Int(n)))*GF(2).root);
BPL := (n,str) -> BP(MatSPL(Z(Log2Int(n), Log2Int(str)))*GF(2).root);

Class(BP, PermClass, rec(
    # p must be a full rank 2-d square matrix of size no larger than 29x29.
    def := function(arg)
        local n, m;

        n := Length(arg);

        if n = 1 and IsMat(arg[1]) then
            m := arg[1];
            n := Dimensions(m)[1];
        else if n > 0 and IsInt(arg[1]) then

            Constraint(ForAny(arg, e -> e < 2^n));
            m := List(arg, e -> _TB(e, n));
        fi; fi;

        # ints in SPIRAL are 29bits long, the upper bits are used for flags
        Constraint(IsInvertibleMat(AMatMat(m)) and Dimensions(m)[1] < 30);

        # NOTE: this is buggy, because fields below are not exposed through .rChildren
        return rec(
            size := 2^Dimensions(m)[1],
            mat:= m,
            fast := List(m, e -> _TD(e)),
            operations := rec(
                Print := (self) >> Print(self.name, "(", PrintCS(self.fast), ")")
            )
        );
    end,

    # NOTE: this is buggy, because .size is not exposed through .rChildren
    domain := self >> self.size,
    range  := self >> self.size,

#    this method converts 'i' to an array of bits, multiplies by the matrix, and converts back
#
#    lambda := self >> let(
#       d := Dimensions(self.params[1])[1],
#       i := Ind(self.size),
#       Lambda(i, todec(self.params[1] * tobin(i,d)))),

#   alternative method: ands a row of the matrix with the input and uses a parity
#   check to see if the bit is set in the output. shifts the output to the proper place. repeat
    lambda := self >> let(
        f := Length(self.fast),
        i := Ind(self.size),
        Lambda(i, Sum(List([1..f], e -> bin_parity(bin_and(self.fast[e], i))*2^(f-e))))),

    transpose := self >> self.__bases__[1](TransposedMat(self.mat))
));

## -----------------------------------------------------------------------------
# CL(N, STR, [E,S,A,R]) - counters a stride L(N, STR) for cache given by [E,S,A,R]
#
# this returns a compound object, namely, P * B where
#
# P = I(N/(E*S)) x L(E*S, Ceil(E*S/STR))
#
# and B is a permutation specified by a function linear on the bits
# which forces the P*B object to span the sets in the cache after L.
#

CL := function(N, STR, CS)
    local E,S,A,Q,P,l,k,i,j, n;

    E := CS[1];
    S := CS[2];

    # deal with degenerate cases and check params.

    # if cache is larger/equal to transform size, no
    # fancy footwork is necessary.
    if E * S >= N then
        return I(N);
    fi;

    # the cache must be large enough, otherwise this method
    # will not build an adequate perm to counteract the stride.
    if S^2 * E < N then
        Error("CL failure: Cache inadequately sized.");
    fi;

    # build the P portion as a bit matrix
    P := MatSPL(DirectSum(
        I(Log2Int(N/(E*S))),
        Z(Log2Int(E*S), Log2Int(E*S) - Log2Int(Maximum(E*S/ Maximum(2*S/E, STR),1)))
#        Z(Log2Int(E*S), Log2Int(E*S) - Log2Int(Maximum(E*S/STR,1)))
    )) * GF(2).root;

    # build the list of 1's in the B matrix.
    l := [];
    k := Log2Int(Minimum(STR, (N/(E*S))));
    i := Log2Int(N/(E*S)) + 1;
    n := Log2Int(N);

    # paranoia check
    if i-k < 1 then
        Error("Problem!!");
    fi;

    A := Copy(P);

    for j in [0..i-2] do
        A[j+1][j+i] := GF(2).root;
    od;

    Q := (TransposedMat(P) * A) - (MatSPL(I(n))*GF(2).root);

    for j in [1..n] do
        for i in [1..n] do
            if Q[j][i] = GF(2).root then
                Add(l, [j,i]);
            fi;
        od;
    od;

    # rebuild P as a normal perm matrix that corresponds to the
    # bit matrix from earlier.
    j := Maximum(E*S/ Maximum(2*S/E, STR),1);

    P := When(E*S = j or j = 1,
        I(N),
        Tensor(
            I(N/(E*S)),
            L(E*S, j)
        )
    );

    # combine the two and return
    # temp -- remove the B matrix, to remove the xor/and/shifts
    # this means we no longer guarantee spanning of the elements/sets
    # but the expressions should reduce better.
    return Compose(P,B(N, l));
end;

#F fB describes a permutation which can be expressed as a sparse linear
#F     function on the bits.
#F
#F I_2^n -> I_2^N
#F
#F params:
#F  n (input size)
#F  N (output size)
#F  l (list of location of 1s in the bit matrix)
#F
#F additional details:
#F   l defines a list of pairs. each pair describes the position
#F   of a 1 in bit matrix of size Nxn. The output mapping is described
#F   by (I + BM)(index), where BM is the sparse bit matrix generated by the
#F   pairs. the pairs themselves are in SPIRAL parlance, that is, [ROW, COL]
#F   where the first row/col is index 1.
#F
#F NOTE:
#F   in order for composition to work like matrix multiplication, the index
#F   is now applied from the LEFT (eg: (index)(I + BM)) instead of from the
#F   right (eg: (I + BM)(index)).
#F
#F example: fB(8,8, [[1,2],[2,3]])
#F
#F [ 1 1 0
#F   0 1 1
#F   0 0 1 ]
#F
#F
#F
Class(fB, FuncClass, rec(
    # full input definition.
    def := (n,N,l) -> rec(),
    range := self >> self.params[2],
    domain := self >> self.params[1],

    # abbreviated input forms, from most complex to simplest.
    abbrevs := [
        (n, N, l) -> Checked(Is2Power(n), Is2Power(N), IsList(l),
            [n,N,l]),
        (n, l) -> Checked(Is2Power(n), IsList(l),
            [n,n,l]),
        (n) -> Checked(Is2Power(n),
            [n,n,[]])
    ],

    transpose := (self) >> self(
        self.params[2],
        self.params[1],
        self._mklist(
            MatAMat(
                InverseAMat(
                    AMatMat(self.bm())
                )
            )
        )
    ),

    # LAMBDA with index on the LEFT: (index)(I + BM)
    lambdaLEFT := self >> let(
        i := Ind(self.params[1]),
        Lambda(i,
            When(Length(self.params[3]) = 0,
                i,
                ApplyFunc(
                    xor,
                    Concat([i], List(self.params[3], e -> let(
                        a := Log2Int(self.params[1]) - e[1],
                        b := Log2Int(self.params[2]) - e[2],
                        When(b = a,
                            bin_and(i, V(2^a)),
                            When(b > a,
                                shl(bin_and(i, V(2^a)), b - a),
                                shr(bin_and(i, V(2^a)), a - b)
                            )
                        )
                    )))
                )
            )
        )
    ),

    # LAMBDA with index on the RIGHT: (I + BM)(index)
    lambdaRIGHT := self >> let(
        i := Ind(self.params[1]),
        Lambda(i,
            When(Length(self.params[3]) = 0,
                i,
                ApplyFunc(
                    xor,
                    Concat([i], List(self.params[3], e -> let(
                        a := Log2Int(self.params[1]) - e[2],
                        b := Log2Int(self.params[2]) - e[1],
                        When(b = a,
                            bin_and(i, V(2^a)),
                            When(b > a,
                                shl(bin_and(i, V(2^a)), b - a),
                                shr(bin_and(i, V(2^a)), a - b)
                            )
                        )
                    )))
                )
            )
        )
    ),

    lambda := self >> self.lambdaLEFT(),

    # a bit more complicated than the B case since matrix is not necessarily
    # square.
    bm := meth(self)
        local n, N, m, minn, minN, j, i;

        n := Log2Int(self.params[1]);
        N := Log2Int(self.params[2]);

        # since we multiply the index from the right, i * BM,
        # and n -> N, the bit matrix is nxN. (n rows, N cols)

        # generate matrix of zeros.
        m := List([1..n], e -> List([1..N], ee -> 0));

        # fill in identity
        minn := When(N > n, 1, n - N + 1);
        minN := When(n > N, 1, N - n + 1);
        for i in [minn..n] do
            m[i][i-minn+minN] := 1;
        od;

        # xor in individual 1s from 'l'
        for i in self.params[3] do
            m[i[1]][i[2]] := BinXor(m[i[1]][i[2]], 1);
        od;

        return m * GF(2).root;
    end,

    # given a bit matrix, make a list.
    _mklist := function(b)
        local n,N, m, minn, minN, i, j, l;

        ## generate identity...
        #

        n := Dimensions(b)[1];
        N := Dimensions(b)[2];

        # generate matrix of zeros.
        m := List([1..n], e -> List([1..N], ee -> GF(2).root*0));

        # fill in identity
        minn := When(N > n, 1, n - N + 1);
        minN := When(n > N, 1, N - n + 1);
        for i in [minn..n] do
            m[i][i-minn+minN] := GF(2).root;
        od;

        ## subtract out identity.
        b := b - m;

        ## add a list entry for each nonzero elem in b.

        l := [];
        for j in [1..Length(b)] do #rows
            for i in [1..Length(b[1])] do # cols
                if b[j][i] = GF(2).root then
                    Add(l, [j,i]);
                fi;
            od;
        od;

        return l;
    end,
));

Class(fB2, fTensorBase, rec(
    __call__ := meth(arg)
        local self, children, lkup, res, h, es;
        self := arg[1];
        es := arg[2];
        children := Flat(Drop(arg, 2));
        if self.skipOneChild and Length(children)=1 then return children[1]; fi;

        h := self.hash;
        if h<>false then
            lkup := h.objLookup(self, children);
            if lkup[1]<>false then return lkup[1]; fi;
        fi;
        res := WithBases(self, rec(es := es, operations := RewritableObjectOps, _children := children));
        if h<>false then return h.objAdd(res, lkup[2]);
        else return res;
        fi;
    end,

    rightBinary  := self >> FoldR1(self._children, (p,x) -> let(base:=self.__bases__[1], base(x, p))),
    leftBinary := self >> FoldL1(self._children, (p,x) -> let(base:=self.__bases__[1], base(p, x))),

    # this works just like the normal fTensor except that
    # subject to some conditions, the variables responsible for the
    # top-end of the range get XORed with variables responsible
    # for the middle of the range.

    lambda := meth(self)
        local es;

        es := self.es;

        # flatten the fTensors first
        # ensure we always work with 2 children
        if self.numChildren() > 2 then
            return self.leftBinary().lambda();
        fi;

        # the expression is now guaranteed to be a left sided
        # binary tree. we need to tell each node/leaf how it is
        # to be split according to the params available to the fB2.

    end,

    combine_op := (self, jv, split, f, g) >> let(a := Error("fB2.lambda()!"), self),
    transpose := self >> self.__bases__[1](List(self.children(), c->c.transpose()))
));


text:
#
# walrus: Computational Methods for Finitely Generated Monoids and Groups
#
#### Utility functions

# Pregroup presentation for triangle group
InstallGlobalFunction(pg_word,
                      {pg, l} -> List(l, x->pg[x]) );

InstallGlobalFunction(Repeat,
                      {n, l} -> ShallowCopy(Flat(ListWithIdenticalEntries(n,l))));

# MaxPowerK: Input a word (relator) v over X, output w such that w^k = v, k
# maximal with this property InstallGlobalFunction(MaxPowerK,
InstallGlobalFunction(MaxPowerK,
function(rel)
    local len, d, divs, isrep,
          checkrep;

    len := Length(rel);
    divs := ShallowCopy(DivisorsInt(len));
    Remove(divs, 1);

    checkrep := function(d)
        local j,k;
        for j in [1..d] do
            for k in [1..(len / d) - 1] do
                if rel[j] <> rel[j + k*d] then
                    return false;
                fi;
            od;
        od;
        return true;
    end;

    for d in divs do
        if checkrep(d) then
            return [ rel{[1..d]}, len / d ];
        fi;
    od;

    return [ rel, 1 ];
end);

InstallGlobalFunction(WalrusTestStandard,
function()
    List(DirectoriesPackageLibrary("walrus", "tst/standard"), TestDirectory);
end);


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

DimLength:=function(l)
  if IsList(l) then
    return Length(l);
  else
    return 1;
  fi;
end;

Hacktype:=function(x)
  if (ObjId(x)=TPtr or ObjId(x)=TArray) then
      return x.t;
  else
      return x;
  fi;
end;

Unify:=function(type,lower)

   if lower=TUnknown then
      return type;
   else
     if type=lower or type=TUnknown then
        return lower;
     else
        if (type=TReal and lower=TComplex) or (type=TComplex and lower=TReal) then
           return TComplex;
	elif (ObjId(lower)=TVect and lower.t=type) then
	    return lower;
	elif (ObjId(type)=TVect and type.t=lower) then
	    return type;
        else
           Error("Type Unification impossible between ",type, " and ",lower, "\n");
        fi;
     fi;
   fi;
end;

Class(Unification, Visitor, rec(
	Multiplication:=meth(self,o,inputs)
	local i,t;
	t:= List(inputs,l->Hacktype(l));
	for i in [1..Length(t)]  do
	   o.TType[i]:=Unify(o.TType[i],t[i]);
	od;
        end,
        ICMultiplication:=meth(self,o,input)
          self.Multiplication(o,input);
        end,
        Glue:=meth(self,o,inputs)
         local i,t;
         t := List(inputs,l->Hacktype(l));
         for i in [1..Length(t)] do
          o.TType[i]:=Unify(o.TType[i],t[i]);
         od;
        end,
       Split:=meth(self,o,inputs)
          o.TType[1]:=Unify(o.TType[1],Flat([inputs])[1].t);
       end,

     Cross:=meth(self,o,inputs)
        local counter,sl1,dim1,dimprev;
        dimprev := 0;
        for counter in [1..Length(o._children)] do
           dim1 := DimLength(o._children[counter].dims()[2]);
           sl1 := SubList(inputs,dimprev+1,dim1+dimprev);
           self(o._children[counter],sl1);
           dimprev := dim1;
        od;
        #dim1 := DimLength(o._children[1].dims()[2]);
        #dim2 := DimLength(o._children[2].dims()[2]);
        #sl1 := SubList(inputs,1,dim1);
        #sl2 := SubList(inputs,dim1+1,dim1+dim2);
        #self(o._children[1],sl1);
        #self(o._children[2],sl2);
     end,

    Addition:=meth(self,o,inputs)
	local i,t;
	t:= List(inputs,l->Hacktype(l));
	for i in [1..Length(t)]  do
	   o.TType[i]:=Unify(o.TType[i],t[i]);
	od;
    end,

    Subtraction:=meth(self,o,inputs)
	local i,t;
	t:= List(inputs,l->Hacktype(l));
	for i in [1..Length(t)]  do
	   o.TType[i]:=Unify(o.TType[i],t[i]);
	od;
    end,

    #Hacks
    Table := meth(self, o, inputs)
	o.TType:=TInt;
    end,

    TableMRC := meth(self, o, inputs)
	o.TType:=TInt;
    end,

    TableSC := meth(self, o, inputs)
        o.TType:=TInt;
    end,

    SUMAcc := meth(self, o, inputs)
	self(o._children[1],inputs);
    end,

    Wire := meth(self, o, inputs)
        local i, t;
        t:= List(inputs,l->Hacktype(l));
	for i in [1..Length(o.rng())]  do
	   o.TType[i]:=Unify(o.TType[1],TInt);
	od;
    end,

    Or:=meth(self,o,inputs)
	local i,t;
	t:= List(inputs,l->Hacktype(l));
	for i in [1..Length(t)]  do
	    o.TType[i]:=Unify(o.TType[i],t[i]);
	od;
    end,

    And:=meth(self,o,inputs)
	local i,t;
	t:= List(inputs,l->Hacktype(l));
	for i in [1..Length(t)]  do
	    o.TType[i]:=Unify(o.TType[i],t[i]);
	od;
    end,

    Equal:=meth(self,o,inputs)
	local i,t;
	t:= List(inputs,l->Hacktype(l));
	for i in [1..Length(t)]  do
	    o.TType[i]:=Unify(o.TType[i],t[i]);
	od;
     end,

     NotEqual:=meth(self,o,inputs)
	local i,t;
	t:= List(inputs,l->Hacktype(l));
	for i in [1..Length(t)]  do
	    o.TType[i]:=Unify(o.TType[i],t[i]);
	od;
     end,

    ExclusiveOr:=meth(self,o,inputs)
	local i,t;
	t:= List(inputs,l->Hacktype(l));
	for i in [1..Length(t)]  do
	    o.TType[i]:=Unify(o.TType[i],t[i]);
	od;
     end,

    Minimums:=meth(self,o,inputs)
	local i,t;
	t:= List(inputs,l->Hacktype(l));
	for i in [1..Length(t)]  do
	    o.TType[i]:=Unify(o.TType[i],t[i]);
	od;
     end,

     Maximums:=meth(self,o,inputs)
	local i,t;
	t:= List(inputs,l->Hacktype(l));
	for i in [1..Length(t)]  do
	    o.TType[i]:=Unify(o.TType[i],t[i]);
	od;
     end,

     AppendToList := (self, o, inputs) >> skip(),

     MoveToNext := (self, o, inputs) >> skip(),

     GathNeighbours := (self, o, inputs) >> skip(),

     GathOne := (self, o, inputs) >> skip(),

     AssignOneFromNine := (self, o, inputs) >> skip(),

     ConstZBitPlane := (self, o, inputs) >> skip(),

     MagPlane := (self, o, inputs) >> skip(),

     MagCube := (self, o, inputs) >> skip(),

     SignPlane := (self, o, inputs) >> skip(),

     CUPCode := (self, o, inputs) >> skip(),

     SetStatus := (self, o, inputs) >> skip(),

     EBCond := meth(self,o,inputs)
        self.(o.A.name)(o.A,inputs);
	self.(o.B.name)(o.B,inputs);
	self.(o.C.name)(o.C,inputs);
     end,

     EBICompose := meth(self, o, inputs)
        self.(o.C.name)(o.C, inputs);
     end,

     EBEncoded := (self, o, inputs) >> skip(),

     EBNoop := (self, o, inputs) >> skip(),

     RLCoding := (self, o, inputs) >> skip(),

     sppPosMod4 := (self, o, inputs) >> skip(),

     sppFalse := (self, o, inputs) >> skip(),

     sppPosMove2 := (self, o, inputs) >> skip(),

     EBLink := (self, o, inputs) >> skip(),

#MQ:

     CodeLPS := (self, o, inputs) >> skip(),

     MQbitStuffing := (self, o, inputs) >> skip(),

     MQnobitStuffing := (self, o, inputs) >> skip(),

     mqBoutClt := (self, o, inputs) >> skip(),

     mqBoutBeq := (self, o, inputs) >> skip(),

     mqBoutCand := (self, o, inputs) >> skip(),

     mqBoutBpp := (self, o, inputs) >> skip(),

     RenormalizationENC := (self, o, inputs) >> skip(),

     mqRenAlt := (self, o, inputs) >> skip(),

     mqRenCTeq := (self, o, inputs) >> skip(),

     MQCond := (self, o, inputs) >> skip(),

     MQDoWhile := (self, o, inputs) >> skip(),

     MQNoop := (self, o, inputs) >> skip(),

     MQLink := (self, o, inputs) >> skip(),

     mqMPSpre := (self, o, inputs) >> skip(),

     mqMPSf := (self, o, inputs) >> skip(),

     mqMPSt := (self, o, inputs) >> skip(),

     mqFlushRegpre := (self, o, inputs) >> skip(),

     mqFlushRegmed := (self, o, inputs) >> skip(),

     mqFlushRegpost := (self, o, inputs) >> skip(),

     MQInit := (self, o, inputs) >> skip(),

     MQBranch := (self, o, inputs) >> skip(),

     MQRetrieve := (self, o, inputs) >> skip(),

     MQLoop := (self, o, inputs) >> skip(),

     Const:=meth(self,o,inputs)
         local t;
         t:= List(inputs,l->Hacktype(l));
	 o.TType[1]:=Unify(o.TType[1],TInt);
     end,

     #NOTE: move to ebcot/unification.gi
     COND_OL := (self, o, inputs) >> skip(),

     Cross:=meth(self,o,inputs)
        local i;
        for i in [1..Length(o._children)] do
	     self(o._children[i],inputs[i]);
        od;
     end,

     ISum:=meth(self,o,inputs) self(o._children[1],inputs); end,
     SMPSum:=meth(self,o,inputs) self(o._children[1],inputs); end,
     ISumAcc:=meth(self,o,inputs) self(o._children[1],inputs); end,
     Compose:=meth(self,o,inputs)
        local ch, numch,counter,z;
	ch := o.children();
	numch := Length(ch);
        for counter in [0..numch-1] do
           self(ch[numch-counter],inputs);
           inputs:=ch[numch-counter].rng();
#	   Print("after step ",counter," Compose is ",inputs,"\n");
        od;
     end,

     VTensor_OL:=meth(self,o,inputs)
       local inp;
       inp:=Copy(inputs);
       inp:=List(inp,x->Cond(ObjId(x)=TPtr,TPtr(TVect(x.t,o.vlen)),ObjId(x)=TArray,TArray(TVect(x.t,o.vlen),x.size/o.vlen),Error("Trying to unify a VTensor with something weird. It should work but i(Fred) just don't know how to do it right now.")));
        self(o._children[1],inp);
     end,
     VTensor:=meth(self,o,input)
       local inputs;
       inputs:=StripList(Copy(input));
       self(o._children[1],Cond(ObjId(inputs)=TPtr, [TPtr(TVect(inputs.t,o.vlen))],ObjId(inputs)=TArray,[TArray(TVect(inputs.t,o.vlen),inputs.size/o.vlen)],Error("Trying to unify a VTensor with something weird. It should work but i(Fred) just don't know how to do it right now.")));
      end,
     BlockVPerm:=meth(self,o,inputs)
            self(o._children[1],[Cond(ObjId(inputs[1])=TArray,TArray(inputs[1].t,inputs[1].size/o.n),"Not handled")]);
      end,

     ScatInit:=meth(self,o,inputs)
         self(o._children, inputs);
     end,

     VScat:=meth(self,o,inputs) o.TType:=Unify(o.TType,Flat([inputs])[1].t); end,
#     VScat_sv:=meth(self,o,inputs) o.TType:=Unify(o.TType,Flat([inputs])[1].t); end,
     VPrm_x_I:=meth(self,o,inputs) o.TType:=Unify(o.TType,Flat([inputs])[1].t); end,
     VGath:=meth(self,o,inputs) o.TType:=Unify(o.TType,Flat([inputs])[1].t); end,
     VGath_dup:=meth(self,o,inputs) o.TType:=Unify(o.TType,Flat([inputs])[1].t); end,
     VScatAcc:=meth(self,o,inputs) o.TType:=Unify(o.TType,Flat([inputs])[1].t); end,
     ScatAcc:=meth(self,o,inputs) o.TType:=Unify(o.TType,Flat([inputs])[1].t); end,
     ICScatAcc :=meth(self,o,inputs) o.TType:=Unify(o.TType,Flat([inputs])[1].t); end,
     Scat:=meth(self,o,inputs) o.TType:=Unify(o.TType,Flat([inputs])[1].t); end,
     Gath:=meth(self,o,inputs) o.TType:=Unify(o.TType,Flat([inputs])[1].t); end,
     Blk:=meth(self,o,inputs) o.TType:=Unify(o.TType,Flat([inputs])[1].t); end,
     VReplicate:=meth(self,o,inputs) o.TType:=Unify(o.TType,Flat([inputs])[1].t); end,
     VHAdd:=meth(self,o,inputs) o.TType:=Unify(o.TType,Flat([inputs])[1].t); end,
     Prm:=meth(self,o,inputs) o.TType:=Unify(o.TType,Flat([inputs])[1].t); end,
     VPerm:=meth(self,o,inputs) o.TType:=Unify(o.TType,Flat([inputs])[1].t); end,
     I:=meth(self,o,inputs) o.TType:=Unify(o.TType,Hacktype(Flat([inputs])[1])); end,
     SUM:=meth(self,o,inputs) DoForAll(o._children,i->self(i,inputs)); end,
     L:=meth(self,o,inputs) o.TType:=Unify(o.TType,Flat([inputs])[1].t); end,
     BB:=meth(self,o,inputs) self(o._children[1],inputs); end,
     LinkIO:=meth(self,o,inputs) self(o.rChildren()[1],inputs); end,
     Buf:=meth(self,o,inputs) self(o._children[1],inputs); end,
     Inplace:=meth(self,o,inputs) self(o._children[1],inputs); end,
     SymSPL:=meth(self,o,inputs) self(o._children[1],inputs); end,
     NoPull:=meth(self,o,inputs) self(o._children[1],inputs); end,

     RecursStepCall:=meth(self,o,inputs) o.TType:=Unify(o.TType,Flat([inputs])[1].t); end,
 ));


text:
# Test of GAP potential for Si system

units		metal
boundary	p p p

atom_style	atomic

read_data	data_gap

pair_style	quip
pair_coeff	* * gap_example.xml "Potential xml_label=GAP_2015_2_20_0_10_54_35_765" 14

neighbor	0.3 bin
neigh_modify	delay 10

fix		1 all nve
thermo		10
timestep	0.001

#dump		1 all custom 10 dump.gap id fx fy fz

run		40

ext: gap


text:
# Just multiplying a vector by itself yields the sum of squares (it's an inner product)
# It's necessary to check for the empty vector though
SumSq := function(v)
	if Size(v) = 0 then
		return 0;
	else
		return v*v;
	fi;
end;

max_issues_repo_name: seanwallawalla-forks/RosettaCodeData

max_forks_repo_name: seanwallawalla-forks/RosettaCodeData


text:
--/**
-- * <copyright>
-- *
-- * Copyright (c) 2010, 2009 IBM Corporation and others.
-- * All rights reserved.   This program and the accompanying materials
-- * are made available under the terms of the Eclipse Public License v2.0
-- * which accompanies this distribution, and is available at
-- * http://www.eclipse.org/legal/epl-v20.html
-- *
-- * Contributors:
-- *   See (or edit) Notice Declaration below
-- *
-- * </copyright>
-- */
--
-- The Complete OCL KeyWord Lexer
--

%options slr
%options fp=OCLKWLexer,prefix=Char_
%options noserialize
%options package=org.eclipse.ocl.xtext.essentialocl.parser
%options template=../lpg/KeywordTemplateF.gi
%options export_terminals=("OCLParsersym.java", "TK_")
%options include_directory="../lpg"

%Import
	EssentialOCLKWLexer.gi
%End

%Notice
	/./**
 * Complete OCL Keyword Lexer
 * <copyright>
 *
 * Copyright (c) 2010, 2009 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *   IBM - Initial API and implementation
 *   E.D.Willink - Bug 292112
 *   Adolfo Sanchez-Barbudo Herrera (Open Canarias) - LPG v 2.0.17 adoption (242153)
 *   Adolfo Sanchez-Barbudo Herrera (Open Canarias) - Introducing new LPG templates (299396)
$copyright_contributions
 *******************************************************************************/
	./
%End

%Export
	inv
	pre
	post
	context
	package
	endpackage
	def
	body
	derive
	init
	--
	-- the following were introduced in the OCL 2.1 RTF 09-05-02.
	--
	static

	OclMessage
%End

%Rules

-- The Goal for the parser is a single Keyword

	KeyWord ::=
		i n v
		/.$BeginAction
			$setResult($_inv);
		  $EndAction
		./

		| p r e
		/.$BeginAction
			$setResult($_pre);
		  $EndAction
		./

		| p o s t
		/.$BeginAction
			$setResult($_post);
		  $EndAction
		./

		| b o d y
		/.$BeginAction
			$setResult($_body);
		  $EndAction
		./

		| c o n t e x t
		/.$BeginAction
			$setResult($_context);
		  $EndAction
		./

		| p a c k a g e
		/.$BeginAction
			$setResult($_package);
		  $EndAction
		./

		| e n d p a c k a g e
		/.$BeginAction
			$setResult($_endpackage);
		  $EndAction
		./

		| d e f
		/.$BeginAction
			$setResult($_def);
		  $EndAction
		./

		| d e r i v e
		/.$BeginAction
			$setResult($_derive);
		  $EndAction
		./

		| i n i t
		/.$BeginAction
			$setResult($_init);
		  $EndAction
		./

		| O c l M e s s a g e
		/.$BeginAction
			$setResult($_OclMessage);
		  $EndAction
		./

		| s t a t i c
		/.$BeginAction
			$setResult($_static);
		  $EndAction
		./
%End


text:
#
# usage: Read(Filename(home_dir,"load.gap"));
#

#
# Polynomials, Root system, Parabolic rootsystems
#
Read(Filename(home_dir,"lib/poly.gd"));
Read(Filename(home_dir,"lib/rsys.gd"));
Read(Filename(home_dir,"lib/psys.gd"));

#
#
#
Read(Filename(home_dir,"lib/chvadj.gd"));
Read(Filename(home_dir,"lib/nilchv.gd"));
Read(Filename(home_dir,"lib/unichv.gd"));
Read(Filename(home_dir,"lib/unimod.gd"));

#
#
#
Read(Filename(home_dir,"lib/algU.gd"));
Read(Filename(home_dir,"lib/witt.gd"));
Read(Filename(home_dir,"lib/unialg.gd"));
Read(Filename(home_dir,"lib/unicls.gd"));

#
# IMPLEMENTATION
#
Read(Filename(home_dir,"lib/poly.gi"));
Read(Filename(home_dir,"lib/rsys.gi"));
Read(Filename(home_dir,"lib/psys.gi"));

Read(Filename(home_dir,"lib/chvadj.gi"));
Read(Filename(home_dir,"lib/nilchv.gi"));
Read(Filename(home_dir,"lib/unichv.gi"));
Read(Filename(home_dir,"lib/unimod.gi"));

Read(Filename(home_dir,"lib/algU.gi"));
Read(Filename(home_dir,"lib/witt.gi"));
Read(Filename(home_dir,"lib/unialg.gi"));
Read(Filename(home_dir,"lib/unicls.gi"));


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

Class(SSE_LDST, rec(
    list := [],
    __call__ := meth(arg)
        local self;
	self := arg[1];
	Append(self.list, Drop(arg, 1));
    end
));

#######################################################################################
# SSE2 2-way 64-bit floating-point instructions
#######################################################################################

vzero_2x64f_const := TVect(TReal, 2).zero();
vzero_2x64f := () -> vzero_2x64f_const;

# Load
#
SSE_LDST(
    Class(vload1sd_2x64f, VecExp_2.unary()),
    Class(vload_1l_2x64f, VecExp_2.binary()),
    Class(vload_1h_2x64f, VecExp_2.binary()),
    Class(vloadu_2x64f,   VecExp_2.unary())
);

# Store
#
SSE_LDST(
    Class(vstore_1l_2x64f, VecStoreCommand.binary()),
    Class(vstore_1h_2x64f, VecStoreCommand.binary()),
    Class(vstoreu_2x64f,   VecStoreCommand.binary())
);

# Binary shuffle
#
Class(vunpacklo_2x64f, VecExp_2.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpacklo(in1, in2, 2, 1)));

Class(vunpackhi_2x64f, VecExp_2.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpackhi(in1, in2, 2, 1)));

Class(vshuffle_2x64f, VecExp_2.binary(), rec(
    semantic := (in1, in2, p) -> shuffle(in1, in2, p, 2, 1),
    params := self >> sparams(2,2),
    ev := self >> self.t.value(self.semantic(self._vval(1),self. _vval(2), self.args[3].p)),
));

# Unary shuffle, sign change
#
Class(vushuffle_2x64f, VecExp_2.unaryFromBinop(vshuffle_2x64f));

Class(chslo_2x64f,     VecExp_2.unary(), rec(
    ev := self >> let(v := self.args[1], v * self.t.value([-1.0, 1.0])),
));

Class(chshi_2x64f,     VecExp_2.unary(), rec(
    ev := self >> let(v := self.args[1], v * self.t.value([1.0, -1.0])),
));

# SSE3 new addsub and hadd instructions
#
Class(addsub_2x64f, VecExp_2.binary(), rec(
    ev := self >> add(self.args[1], chslo_2x64f(self.args[2]))
));
Class(hadd_2x64f,   VecExp_2.binary());

#######################################################################################
# SSE2 2-way 64-bit integer instructions
# NOTE: use TFixedPt instead of TReal in as the type in below instructions
#######################################################################################

vzero_2x64i_const := TVect(TReal, 2).zero();
vzero_2x64i := () -> vzero_2x64i_const;

# Binary shuffle
#
Class(vunpacklo_2x64i, VecExp_2.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpacklo(in1, in2, 2, 1)
));

Class(vunpackhi_2x64i, VecExp_2.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpackhi(in1, in2, 2, 1)
));

Class(vshuffle_2x64i, VecExp_2.binary(), rec(
    semantic := (in1, in2, p) -> shuffle(in1, in2, p, 2, 1),
    params := self >> sparams(2,2)
));

# Unary shuffle, sign change
#
Class(vushuffle_2x64i, VecExp_2.unaryFromBinop(vshuffle_2x64i));
Class(chslo_2x64i,     VecExp_2.unary());
Class(chshi_2x64i,     VecExp_2.unary());

# cmpge_2x64f
Class(cmpge_2x64f,  VecExp_2.binary());
Class(cmple_2x64f,  VecExp_2.binary());
Class(cmpeq_2x64f,  VecExp_2.binary());

#######################################################################################
# SSE2 2-way 32-bit floating-point instructions
# this architecture simulates 2-way inside 4-way
#######################################################################################

vzero_2x32f_const := TVect(TReal, 2).zero();
vzero_2x32f := () -> vzero_2x32f_const;

# Load
#
SSE_LDST(
    Class(vload1sd_2x32f, VecExp_2.unary()),
    Class(vload_1l_2x32f, VecExp_2.binary()),
    Class(vload_1h_2x32f, VecExp_2.binary()),
    Class(vload_2x32f,    VecExp_2.binary()),
    Class(vloadu_2x32f,   VecExp_2.unary())
);

# Store
#
SSE_LDST(
    Class(vstore_1l_2x32f, VecExpCommand),
    Class(vstore_1h_2x32f, VecExpCommand),
    Class(vstore_2x32f,    VecExpCommand),
    Class(vstoreu_2x32f,   VecExpCommand)
);

# Binary shuffle
#
Class(vunpacklo_2x32f, VecExp_2.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpacklo(in1, in2, 2, 1)
));

Class(vunpackhi_2x32f, VecExp_2.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpackhi(in1, in2, 2, 1)
));

Class(vshuffle_2x32f, VecExp_2.binary(), rec(
    semantic := (in1, in2, p) -> shuffle(in1, in2, p, 2, 1),
    params := self >> sparams(2,2)
));

# Unary shuffle, sign change
#
Class(vushuffle_2x32f, VecExp_2.unaryFromBinop(vshuffle_2x32f));
Class(chslo_2x32f, VecExp_2.unary());
Class(chshi_2x32f, VecExp_2.unary());

# SSE3 new addsub and hadd instructions
#
Class(addsub_2x32f, VecExp_2.binary());
Class(hadd_2x32f,   VecExp_2.binary());

#######################################################################################
#   SSE 4-way 32-bit float instructions
#######################################################################################

vzero_4x32f_const := TVect(T_Real(32), 4).zero();
vzero_4x32f := () -> vzero_4x32f_const;

# Load
#
SSE_LDST(
    Class(vload1_4x32f,   VecExp_4.unary()),
    Class(vload_2l_4x32f, VecExp_4.binary()),
    Class(vload_2h_4x32f, VecExp_4.binary()),
    Class(vloadu_4x32f,   VecExp_4.unary()),
    Class(vloadu2_4x32f,  VecExp_4.unary()),
    Class(vinsert_4x32f,  VecExp_4.binary())
);

# Store
#
SSE_LDST(
    Class(vstore1_4x32f,   VecStoreCommand.binary()),
    Class(vstore_2l_4x32f, VecStoreCommand.binary()),
    Class(vstore_2h_4x32f, VecStoreCommand.binary()),
    Class(vstoreu_4x32f,   VecStoreCommand.binary()),
    Class(vstoreu2_4x32f,  VecStoreCommand.binary()), # cprint: self.loc.svcprint(16)
    Class(vstoremsk_4x32f, VecStoreCommand.binary()),   # cprint: self.loc.svcprint(8)
    Class(vextract_4x32f,  VecStoreCommand.binary())
);

# Binary shuffle
#
Class(vunpacklo_4x32f, VecExp_4.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpacklo(in1, in2, 4, 1),
));

Class(vunpackhi_4x32f, VecExp_4.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpackhi(in1, in2, 4, 1),
));

Class(vshuffle_4x32f,  VecExp_4.binary(), rec(
    semantic := (in1, in2, p) -> shuffle(in1, in2, p, 4, 1),
    params := self >> sparams(4,4),
    permparams := iperm4,
    ev := self >> self.t.value(self.semantic(self._vval(1),self._vval(2), self.args[3].p)),
));

# Unary shuffle
#
Class(vushuffle_4x32f, VecExp_4.unaryFromBinop(vshuffle_4x32f), rec(
    ev := self >> self.t.value(self.semantic(self._vval(1), self.args[2].p)),
));

Class(chshi_4x32f,  VecExp_4.unary(), rec(
    ev := self >> let( v := self.args[1], v * self.t.value([1.0, -1.0, 1.0, -1.0]) )
));

Class(chslo_4x32f,  VecExp_4.unary(), rec(
    ev := self >> let( v := self.args[1], v * self.t.value([-1.0, 1.0, -1.0, 1.0]) )
));

Class(vldup_4x32f,  VecExp_4.unary(), rec(
    ev := self >> let( v := self._vval(1), self.t.value([v[1], v[1], v[3], v[3]]) )
));
Class(vhdup_4x32f,  VecExp_4.unary(), rec(
    ev := self >> let( v := self._vval(1), self.t.value([v[2], v[2], v[4], v[4]]) )
));

# horizontal add
Class(alignr_4x32f, VecExp_4.binary());

#######################################################################################
#   SSE 4-way 32-bit integer instructions
#######################################################################################

vzero_4x32i_const := TVect(TReal, 4).zero();
vzero_4x32i := () -> vzero_4x32i_const;

Class(vloadu_4x32i, VecExp_4.unary());
Class(vstoreu_4x32i, VecExpCommand);

# Binary shuffle
#
Class(vunpacklo_4x32i, VecExp_4.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpacklo(in1, in2, 4, 1)));

Class(vunpackhi_4x32i, VecExp_4.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpackhi(in1, in2, 4, 1)));

Class(vpacks_4x32i, VecExp_4.binary(), rec(
    semantic := (in1, in2, p) -> pack_semantic(in1, in2, 4),
    computeType := self >> TVect(T_Int(16), 8)));

Class(vshuffle_4x32i, VecExp_4.binary(), rec(
    semantic := (in1, in2, p) -> shuffle(in1, in2, p, 4, 1),
    params := self >> sparams(4,4),
    permparams := iperm4
));

# Unary shuffle
#
Class(vushuffle_4x32i, VecExp_4.unaryFromBinop(vshuffle_4x32i));

# for Viterbi
Class(interleavedmask_4x32i, VecExp_4.binary(), rec(
    computeType := self >> TUChar
));

#_mm_testz_si128
Class(testz_4x32i, VecExp_4.binary(), rec(
    computeType := self >> TInt
));

#_mm_testc_si128
Class(testc_4x32i, VecExp_4.binary(), rec(
    computeType := self >> TInt
));

#_mm_testnzc_si128
Class(testnzc_4x32i, VecExp_4.binary(), rec(
    computeType := self >> TInt
));

# SSE3 new addsub and hadd instructions
#
Class(addsub_4x32f, VecExp_4.binary(), rec(
    ev := self >> add(self.args[1], chslo_4x32f(self.args[2]))
));

Class(hadd_4x32f,   VecExp_4.binary());

# type conversion of lower two elements from 4x32f to 2x64f
Class(vcvt_64f32f, VecExp_4.unary(), rec(
    computeType := (self) >> TVect(T_Real(64), 2)
));

# type conversion of 2x64f to lower two of 4x32f
Class(vcvt_32f64f, VecExp_2.unary(), rec(
    computeType := (self) >> TVect(T_Real(32), 4)
));

# type conversion 4x32i to 4x32f
Class(vcvt_4x32_i2f, VecExp_4.unary(), rec(
    computeType := (self) >> TVect(T_Real(32), 4)
));

# type conversion 4x32f to 4x32i, rounding acording MXCSR register rules
Class(vcvt_4x32_f2i, VecExp_4.unary(), rec(
    computeType := (self) >> TVect(T_Int(32), 4)
));

# type conversion 4x32f to 4x32i, truncation toward zero
Class(vcvtt_4x32_f2i, VecExp_4.unary(), rec(
    computeType := (self) >> TVect(T_Int(32), 4)
));

#######################################################################################
#   SSE2 8-way 16-bit integer instructions
#######################################################################################

vzero_8x16i_const := TVect(TReal, 8).zero();
vzero_8x16i := () -> vzero_8x16i_const;

# SSSE3 sign change instructions
Class(chs_8x16i, VecExp_8.binary());

# Load
#
SSE_LDST(
    Class(vload1_8x16i, VecExp_8.ternary()),
    Class(vload2_8x16i, VecExp_8.unary()),
    Class(vload4_8x16i, VecExp_8.unary()),
    Class(vloadu_8x16i, VecExp_8.unary())
);

# Store
#
SSE_LDST(
    Class(vextract1_8x16i, VecExpCommand, rec(numargs := 2)),
    Class(vextract2_8x16i, VecExpCommand, rec(numargs := 1)),
    Class(vstoreu_8x16i,   VecExpCommand),
    Class(vstore4_8x16i,   VecExpCommand),
    Class(vstoremsk_8x16i, VecExpCommand)
);

# Binary shuffle
#
Class(vunpacklo_8x16i, VecExp_8.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpacklo(in1, in2, 8, 1)));

Class(vunpackhi_8x16i, VecExp_8.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpackhi(in1, in2, 8, 1)));

Class(vunpacklo2_8x16i, VecExp_8.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpacklo(in1, in2, 8, 2)));

Class(vunpackhi2_8x16i, VecExp_8.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpackhi(in1, in2, 8, 2)));

Class(vunpacklo4_8x16i, VecExp_8.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpacklo(in1, in2, 8, 4)));

Class(vunpackhi4_8x16i, VecExp_8.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpackhi(in1, in2, 8, 4)));

Class(vpacks_8x16i, VecExp_8.binary(), rec(
    semantic := (in1, in2, p) -> pack_semantic(in1, in2, 16),
    computeType := self >> TVect(T_Int(8), 16)));

Class(vpackus_8x16i, VecExp_8.binary(), rec(
    semantic := (in1, in2, p) -> pack_semantic(in1, in2, 16),
    computeType := self >> TVect(T_UInt(8), 16)));

Class(vshuffle2_8x16i, VecExp_8.binary(), rec(
    semantic := (in1, in2, p) -> shuffle(in1, in2, p, 8, 2),
    params := self >> sparams(4,4),
    permparams := iperm4
));

Class(vshuffle4_8x16i, VecExp_8.binary(), rec(
    semantic := (in1, in2, p) -> shuffle(in1, in2, p, 8, 4),
    params := self >> sparams(2,2),
));

# Unary shuffle
#
Class(vushuffle2_8x16i, VecExp_8.unaryFromBinop(vshuffle2_8x16i), rec(
    params := self >> sparams(4,4),
    permparams := iperm4,
));

Class(vushufflelo_8x16i, VecExp_8.unary(), rec(
    params := self >> sparams(4,4),
    permparams := iperm4,
    semantic := (in1, p) -> shufflelo(in1, p, 8, 1)));  #Complicated, buggy?

Class(vushufflehi_8x16i, VecExp_8.unary(), rec(
    params := self >> sparams(4,4),
    permparams := iperm4,
    semantic := (in1, p) -> shufflehi(in1, p, 8, 1)));  #Complicated, buggy?

# SSSE3 unary shuffle
Class(vushuffle_8x16i, VecExp_8.binary());

# for Viterbi
Class(interleavedmask_8x16i, VecExp_8.binary(), rec(
        computeType := self >> TSym("short int")
));

Class(alignr_8x16i, VecExp_8.binary());

# cmplt_8x16i
Class(cmplt_8x16i,  VecExp_8.binary());

#_mm_testz_si128
Class(testz_8x16i, VecExp_8.binary(), rec(
    computeType := self >> TInt
));
#_mm_testc_si128
Class(testc_8x16i, VecExp_8.binary(), rec(
    computeType := self >> TInt
));

#_mm_testnzc_si128
Class(testnzc_8x16i, VecExp_8.binary(), rec(
    computeType := self >> TInt
));

#######################################################################################
#   SSE2 16-way 8-bit integer instructions
#######################################################################################

Class(vushuffle_16x8i, VecExp_16.unary(), rec(
    params := self >> sparams(4,4),
));

# Load/Store
#
SSE_LDST(
    Class(vloadu_16x8i,    VecExp_16.unary()),
    Class(vstoreu_16x8i,   VecExpCommand),
    Class(vstoremsk_16x8i, VecExpCommand)
);

# Binary shuffle
#
Class(vunpacklo_16x8i, VecExp_16.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpacklo(in1, in2, 16, 1)));

Class(vunpackhi_16x8i, VecExp_16.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpackhi(in1, in2, 16, 1)));

Class(vunpacklo2_16x8i, VecExp_16.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpacklo(in1, in2, 16, 2)));

Class(vunpackhi2_16x8i, VecExp_16.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpackhi(in1, in2, 16, 2)));

Class(vunpacklo4_16x8i, VecExp_16.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpacklo(in1, in2, 16, 4)));

Class(vunpackhi4_16x8i, VecExp_16.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpackhi(in1, in2, 16, 4)));

Class(vunpacklo8_16x8i, VecExp_16.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpacklo(in1, in2, 16, 8)));

Class(vunpackhi8_16x8i, VecExp_16.binary(), _ev_binop_semantic_mixin, rec(
    semantic := (in1, in2, p) -> unpackhi(in1, in2, 16, 8)));

Class(vshuffle4_16x8i, VecExp_16.binary(), rec(
    semantic := (in1, in2, p) -> shuffle(in1, in2, p, 16, 4),
    params := self >> sparams(4,4),
    permparams := iperm4
));

Class(vshuffle8_16x8i, VecExp_16.binary(), rec(
    semantic := (in1, in2, p) -> shuffle(in1, in2, p, 16, 8),
    params := self >> sparams(2,2),
));

# Unary shuffles
#
Class(vushuffle4_16x8i, vushuffle_16x8i, rec(
    semantic := (in1, p) -> shuffle(in1, in1, p, 16, 4)));

Class(vushufflelo2_16x8i, vushuffle_16x8i, rec(
    semantic := (in1, p) -> shufflelo(in1, p, 16, 2)));

Class(vushufflehi2_16x8i, vushuffle_16x8i, rec(
    semantic := (in1, p) -> shufflehi(in1, p, 16, 2)));

# Viterbi
#
Class(interleavedmaskhi_16x8i, VecExp_8.binary(), rec(
    computeType := self >> TSym("short int")));

Class(interleavedmasklo_16x8i, VecExp_8.binary(), rec(
    computeType := self >> TSym("short int")));

Class(average_16x8i, VecExp_16.binary());

Class(vmovemask_16x8i, VecExp_16.unary(), rec(
    computeType := self >> T_UInt(16)));

Class(vcastizxlo, castizx, rec(
    ev := self >> vtakelo(self.args[1].t.toUnsigned().value(self.args[1].ev()))
));

Class(vcastizxhi, castizx, rec(
    ev := self >> vtakehi(self.args[1].t.toUnsigned().value(self.args[1].ev()))
));

Class(vcastuzxlo, castuzx, rec(
    ev := self >> vtakelo(self.args[1].t.toUnsigned().value(self.args[1].ev()))
));

Class(vcastuzxhi, castuzx, rec(
    ev := self >> vtakehi(self.args[1].t.toUnsigned().value(self.args[1].ev()))
));


text:
InstallGlobalFunction(MitM_OMRecToXML,
function(r)
    local str, rnam, attributes, content, item;
    str := StringFormatted("<{}", MitM_Tag(r));
    attributes := MitM_Attributes(r);
    if attributes <> fail then
        for rnam in Set(RecNames(attributes)) do
            Append(str, StringFormatted(" {}=\"{}\"",
                                        rnam, attributes.(rnam)));
        od;
    fi;
    if MitM_Content(r) <> fail then
        Append(str, ">");
        content := MitM_Content(r);
        if Length(content) = 1 and not MitM_OMRec(content[1]) then
            Append(str, String(content[1]));
        elif Length(content) > 0 then
            Append(str, "\n");
            for item in content do
                if MitM_OMRec(item) then
                    Append(str, MitM_OMRecToXML(item));
                else
                    # This might not be possible with a proper OMRec, since a
                    # string always appears inside a pair of tags, on its own.
                    Append(str, String(item));
                fi;
                Append(str, "\n");
            od;
        fi;
        Append(str, StringFormatted("</{}>", MitM_Tag(r)));
    else
        Append(str, " />");
    fi;
    return str;
end);

max_stars_repo_name: markuspf/MathsInTheMiddle

max_issues_repo_name: markuspf/MathsInTheMiddle

max_forks_repo_name: markuspf/MathsInTheMiddle


text:
# Function composition
Composition := function(f, g)
  local h;
  h := function(x)
    return f(g(x));
  end;
  return h;
end;

# Apply each function in list u, to argument x
ApplyList := function(u, x)
  local i, n, v;
  n := Size(u);
  v := [ ];
  for i in [1 .. n] do
    v[i] := u[i](x);
  od;
  return v;
end;

# Inverse and Sqrt are in the built-in library. Note that GAP doesn't have real numbers nor floating point numbers. Therefore, Sqrt yields values in cyclotomic fields.
# For example,
#    gap> Sqrt(7);
#    E(28)^3-E(28)^11-E(28)^15+E(28)^19-E(28)^23+E(28)^27
# where E(n) is a primitive n-th root of unity
a := [ i -> i + 1, Inverse, Sqrt ];
# [ function( i ) ... end, <Operation "InverseImmutable">, <Operation "Sqrt"> ]
b := [ i -> i - 1, Inverse, x -> x*x ];
# [ function( i ) ... end, <Operation "InverseImmutable">, function( x ) ... end ]

# Compose each couple
z := ListN(a, b, Composition);

# Now a test
ApplyList(z, 3);
[ 3, 3, 3 ]

max_stars_repo_name: djgoku/RosettaCodeData

max_issues_repo_name: djgoku/RosettaCodeData

max_forks_repo_name: djgoku/RosettaCodeData


text:
#
# Read("~/Workspace/groupsSB/epi/A2/actionFromExt1.gi");
#

type:="A";
rank:=2;
nr_pos_roots:=3;
highest_weight:=[1,1];# corresponding highest weight module is the Lie algebra

L:= SimpleLieAlgebra(type,rank,Rationals);
cb0:=CanonicalBasis(L);
V:= HighestWeightModule( L, highest_weight );
extA:=List([1..Dimension(V)],i->ExteriorPowerOfAlgebraModule( V, i ));
extA_basis:=List(extA,i->Basis(i));

extA1:=extA[1];
extA1b:=extA_basis[1];

#extA:=List([1..Dimension(V)],i->ExteriorPower( i ,V ));

ext1e:=function(e)
	local extb,result,v;
    extb:=extA_basis[1];

	result:=[];
	for v in extb do
		Append(result,[Coefficients(extb,e^v)]);
	od;
	result:=TransposedMat(result);
	return result;
end;

ext1_root_group:=function(index,t)
	local ee,tmp,result,i;
	ee:=ext1e(cb0[index]);
	tmp:=ee;
	result:=tmp^0;
	i:=1;
	while Length(Set(Concatenation(tmp)))<>1 do
		result:=result+t^i*tmp/Factorial(i);
		i:=i+1;
		tmp:=tmp*ee;
	od;
	return result;
end;

ext1_coeff_comb:=function(coeffs)
    local result,extb;
    extb:=extA_basis[1];
    result:=List([1..Length(extb)],i->coeffs[i]*extb[i]);
    return Sum(result);
end;

ext1_root_group_basis_img:=function(index,t)
    local rg,result;
    rg:=ext1_root_group(index,t);
    rg:=TransposedMat(rg);
    result:=List(rg,l->ext1_coeff_comb(l));
    return result;
end;

# ObjByExtRep(FamilyObj(bbb[1]),ExtRepOfObj(bbb[1]));

u1Bimg:=ext1_root_group_basis_img(1,1);

qqq:=ExtRepOfObj(extA_basis[2][1]);
IsWedgeElement(qqq);
ConvertToNormalFormMonomialElement(qqq);

n:=2;
fam:=FamilyObj(qqq);
combs:= Combinations( [1..Dimension(L)], n );
gens:= List( combs, x -> Basis(L){x} );
F:=LeftActingDomain(L);
gens2:= List( gens, x -> ObjByExtRep( fam, [ x , One(F) ] ) );

for i in [1..Length(gens)] do
    gens2[i]![2]:= true;
od;

test:=[2,2];
test:=Basis(L){test};
test:=ObjByExtRep( fam, [ test , One(F) ] );
test![2]:=true;
test:=ConvertToNormalFormMonomialElement(test);

M:=AdjointModule(L);
extA2:=ExteriorPowerOfAlgebraModule(M,2);

#
#
#
extA1:=extA[1];
bv:=BasisVectors(Basis(extA1));
bb:=ext1_root_group_basis_img(1,1);
B:= Algebra( Rationals, bb, "basis" );
#AlgebraHomomorphismByImages( extA1, extA1, bv, bb )

LeftModuleGeneralMappingByImages( extA1, extA1, bv, bb );
LeftModuleHomomorphismByImages( extA1, extA1, bv, bb );

max_stars_repo_name: iuliansimion/groupsSB

max_issues_repo_name: iuliansimion/groupsSB

max_forks_repo_name: iuliansimion/groupsSB


text:
--/**
-- * <copyright>
-- *
-- * Copyright (c) 2008 Eclipse.org and others.
-- * All rights reserved.   This program and the accompanying materials
-- * are made available under the terms of the Eclipse Public License v2.0
-- * which accompanies this distribution, and is available at
-- * http://www.eclipse.org/legal/epl-v20.html
-- *
-- * Contributors:
-- *   E.D. Willink - Initial API and implementation
-- *   Adolfo Sanchez-Barbudo Herrera (Open Canarias):
-- *        - 242153: LPG v 2.0.17 adoption.
-- *        - 299396: Introducing new LPG templates.
-- *        - 300534: Removing the use of deprecated macros.
-- *
-- * </copyright>
-- */
--
-- Additional ERROR_TOKEN rules for The OCL Parser
--

%Import
	OCLParser.g
%End

%Import
	EssentialOCLErrors.gi
%End

%Rules

-----------------------------------------------------------------------
--	Calls
-----------------------------------------------------------------------
	OclMessageExpCS ::= primaryExpCS '^^' simpleNameCS ERROR_TOKEN
		/.$NewCase./
	OclMessageExpCS ::= primaryExpCS '^' simpleNameCS ERROR_TOKEN
		/.$BeginCode
					reportErrorTokenMessage(getRhsTokenIndex(2), OCLParserErrors.MISSING_MESSAGE_ARGUMENTS);
					OCLExpressionCS target = (OCLExpressionCS)getRhsSym(1);
					MessageExpCS result = createMessageExpCS(
							target,
							getRhsIToken(2).getKind() == $sym_type.TK_CARET,
							(SimpleNameCS)getRhsSym(3),
							new BasicEList<OCLMessageArgCS>()
						);
					setOffsets(result, target, getRhsIToken(4));
					setResult(result);
		  $EndCode
		./

-----------------------------------------------------------------------
--	Contexts
-----------------------------------------------------------------------
	classifierContextDeclCS ::= context pathNameCS ERROR_TOKEN
		/.$BeginCode
					reportErrorTokenMessage(getRhsTokenIndex(3), OCLParserErrors.MISSING_INV_OR_DEF);
					ClassifierContextDeclCS result = createClassifierContextDeclCS(
							null,
							(PathNameCS)getRhsSym(2),
							new BasicEList<InvOrDefCS>()
						);
					setOffsets(result, getRhsIToken(1), getRhsIToken(3));
					setResult(result);
		  $EndCode
		./

	defExpressionCS ::= typedUninitializedVariableCS ERROR_TOKEN
		/.$BeginCode
					reportErrorTokenMessage(getRhsTokenIndex(2), OCLParserErrors.MISSING_EQUALS);
					VariableCS variableCS = (VariableCS)getRhsSym(1);
					DefExpressionCS result = createDefExpressionCS(
							variableCS,
							null,
							null
						);
					setOffsets(result, variableCS, getRhsIToken(2));
					setResult(result);
		  $EndCode
		./
	defExpressionCS ::= simpleNameCS ERROR_Colon
		/.$BeginCode
					SimpleNameCS name = (SimpleNameCS)getRhsSym(1);
					VariableCS variableCS = createVariableCS(name, null, null);
					setOffsets(variableCS, name, getRhsIToken(2));
					DefExpressionCS result = createDefExpressionCS(
							variableCS,
							null,
							null
						);
					setOffsets(result, variableCS, getRhsIToken(2));
					setResult(result);
		  $EndCode
		./

	invOrDefCS ::= inv unreservedSimpleNameCS ERROR_Colon
		/.$BeginCode
					InvCS result = createInvCS(
							(SimpleNameCS)getRhsSym(2),
							null
						);
					setOffsets(result, getRhsIToken(1), getRhsIToken(3));
					setResult(result);
		  $EndCode
		./
    invOrDefCS ::= def unreservedSimpleNameCS ERROR_Colon
        /.$BeginCode
                    DefCS result = createDefCS(
                            false,
                            (SimpleNameCS)getRhsSym(2),
                            null
                        );
                    setOffsets(result, getRhsIToken(1), getRhsIToken(3));
                    setResult(result);
          $EndCode
        ./
    invOrDefCS ::= static def unreservedSimpleNameCS ERROR_Colon
        /.$BeginCode
                    DefCS result = createDefCS(
                            true,
                            (SimpleNameCS)getRhsSym(3),
                            null
                        );
                    setOffsets(result, getRhsIToken(1), getRhsIToken(4));
                    setResult(result);
          $EndCode
        ./

	operationCS1 ::= simpleNameCS '(' parametersCSopt ')' ERROR_Colon
		/.$BeginCode
					OperationCS result = createOperationCS(
							getRhsIToken(1),
							new BasicEList<VariableCS>(),
							null
						);
					setOffsets(result, getRhsIToken(1), getRhsIToken(5));
					setResult(result);
		  $EndCode
		./
	operationCS1 ::= simpleNameCS ERROR_TOKEN
		/.$BeginCode
					reportErrorTokenMessage(getRhsTokenIndex(2), OCLParserErrors.MISSING_LPAREN);
					OperationCS result = createOperationCS(
							getRhsIToken(1),
							new BasicEList<VariableCS>(),
							null
						);
					setOffsets(result, getRhsIToken(1), getRhsIToken(2));
					setResult(result);
		  $EndCode
		./
	operationCS1 ::= ERROR_TOKEN
		/.$BeginCode
					reportErrorTokenMessage(getRhsTokenIndex(1), OCLParserErrors.MISSING_IDENTIFIER);
					OperationCS result = createOperationCS(
							getRhsIToken(1),
							new BasicEList<VariableCS>(),
							null
						);
					setOffsets(result, getRhsIToken(1));
					setResult(result);
		  $EndCode
		./
	operationCS2 ::= pathNameCS '::' unreservedSimpleNameCS '(' parametersCSopt ')' ERROR_Colon
		/.$BeginCode
					PathNameCS pathNameCS = (PathNameCS)getRhsSym(1);
					SimpleNameCS simpleNameCS = (SimpleNameCS)getRhsSym(3);
					OperationCS result = createOperationCS(
							pathNameCS,
							simpleNameCS,
							(EList<VariableCS>)getRhsSym(5),
							null
						);
					setOffsets(result, pathNameCS, getRhsIToken(7));
					setResult(result);
		  $EndCode
		./
	operationCS2 ::= pathNameCS '::' ERROR_SimpleNameCS
		/.$BeginCode
					PathNameCS pathNameCS = (PathNameCS)getRhsSym(1);
					SimpleNameCS simpleNameCS = (SimpleNameCS)getRhsSym(3);
					OperationCS result = createOperationCS(
							pathNameCS,
							simpleNameCS,
							new BasicEList<VariableCS>(),
							null
						);
					setOffsets(result, pathNameCS, simpleNameCS);
					setResult(result);
		  $EndCode
		./

	prePostOrBodyDeclCS ::= pre unreservedSimpleNameCS ERROR_Colon
		/.$BeginCode
					PrePostOrBodyDeclCS result = createPrePostOrBodyDeclCS(
							PrePostOrBodyEnum.PRE_LITERAL,
							(SimpleNameCS)getRhsSym(2),
							createInvalidLiteralExpCS(getRhsTokenText(3))
						);
					setOffsets(result, getRhsIToken(1), getRhsIToken(3));
					setResult(result);
		  $EndCode
		./
	prePostOrBodyDeclCS ::= post unreservedSimpleNameCS ERROR_Colon
		/.$BeginCode
					PrePostOrBodyDeclCS result = createPrePostOrBodyDeclCS(
							PrePostOrBodyEnum.POST_LITERAL,
							(SimpleNameCS)getRhsSym(2),
							createInvalidLiteralExpCS(getRhsTokenText(3))
						);
					setOffsets(result, getRhsIToken(1), getRhsIToken(3));
					setResult(result);
		  $EndCode
		./
	prePostOrBodyDeclCS ::= body unreservedSimpleNameCS ERROR_Colon
		/.$BeginCode
					PrePostOrBodyDeclCS result = createPrePostOrBodyDeclCS(
							PrePostOrBodyEnum.BODY_LITERAL,
							(SimpleNameCS)getRhsSym(2),
							createInvalidLiteralExpCS(getRhsTokenText(3))
						);
					setOffsets(result, getRhsIToken(1), getRhsIToken(3));
					setResult(result);
		  $EndCode
		./

	initOrDerValueCS ::= init ERROR_Colon
		/.$BeginCode
					InitValueCS result = createInitValueCS(null);
					setOffsets(result, getRhsIToken(2), getRhsIToken(3));
					setResult(result);
		  $EndCode
		./
	initOrDerValueCS ::= derive ERROR_Colon
		/.$BeginCode
					DerValueCS result = createDerValueCS(null);
					setOffsets(result, getRhsIToken(2), getRhsIToken(3));
					setResult(result);
		  $EndCode
		./

	packageDeclarationCS_A ::= package pathNameCS contextDeclsCSopt ERROR_Empty endpackage
		/.$BeginCode
					PackageDeclarationCS result = createPackageDeclarationCS(
							(PathNameCS)getRhsSym(2),
							(EList<ContextDeclCS>)getRhsSym(3)
						);
					setOffsets(result, getRhsIToken(1), getRhsIToken(5));
					setResult(result);
		  $EndCode
		./
	packageDeclarationCS_A ::= package pathNameCS contextDeclsCSopt ERROR_TOKEN
		/.$BeginCode
					reportErrorTokenMessage(getRhsTokenIndex(4), OCLParserErrors.MISSING_ENDPACKAGE);
					PackageDeclarationCS result = createPackageDeclarationCS(
							(PathNameCS)getRhsSym(2),
							(EList<ContextDeclCS>)getRhsSym(3)
						);
					setOffsets(result, getRhsIToken(1), getRhsIToken(4));
					setResult(result);
		  $EndCode
		./
%End


text:
#
# usage:
# Read("~/Workspace/Chevalley.gap/init.gap"); Read(Filename(home_dir,"load.gap")); Read(Filename(home_dir,"main.gap"));
#
# Read(Filename(home_dir,"main.gap"));
#

ITER_POLY_WARN:=false;
Read(Filename(home_dir,"lib/io.gi"));
Read(Filename(home_dir,"handle.gap"));

alg:=AlgebraicU("G",2,GF(2));
#alg:=AlgebraicU(sys);

orbs:=UnipotentClasses(alg,"");

infos:=List(AllClasses(orbs),orb->handleClassShort(orb));


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

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

warpxOpts := function(arg) # specific to WarpX size 100...
    local opts, rfs;

    rfs := Copy(RulesFuncSimp);
    Unbind(rfs.rules.TensorIdId);

    opts := Copy(WarpXOpts);
    opts.breakdownRules.Circulant := [Circulant_PRDFT_FDataNT];
    opts.breakdownRules.PRDFT := List([PRDFT1_Base1, PRDFT1_Base2, CopyFields(PRDFT1_CT,
            rec(allChildren := P ->Filtered(PRDFT1_CT.allChildren(P), i->When(P[1] = 100, Cols(i[1]) = 4, true)))),
        PRDFT_PD], _noT);
    opts.breakdownRules.IPRDFT := List([ IPRDFT1_Base1, IPRDFT1_Base2, IPRDFT1_CT, IPRDFT_PD ], _noT);
    opts.breakdownRules.PRDFT3 := List([ PRDFT3_Base1, PRDFT3_Base2, PRDFT3_CT ], _noT);
    opts.breakdownRules.IPRDFT2 := List([ IPRDFT2_Base1, IPRDFT2_Base2, IPRDFT2_CT ], _noT);
    opts.breakdownRules.DFT := [ DFT_Base,
        CopyFields(DFT_CT, rec(children := nt ->Filtered(DFT_CT.children(nt), i->When(nt.params[1] = 100, Cols(i[1]) = 4, true)))),
        DFT_PD ];
    opts.breakdownRules.TTensorInd := [dsA_base, L_dsA_L_base, dsA_L_base, L_dsA_base];
    opts.breakdownRules.MDDFT := [ MDDFT_Base, MDDFT_RowCol ];
    opts.breakdownRules.TL := [L_base];
    opts.breakdownRules.TSparseMat := [ TSparseMat_base ];

    opts.globalUnrolling := 23;
    opts.codegen := CopyFields( MultiPtrCodegenMixin, spiral.libgen.VecRecCodegen);
    opts.sumsgen.IterHStack := MultiPtrSumsgenMixin.IterHStack;
    opts.preProcess := t -> ApplyStrategy(t,
                    [ RulesFFTXPromoteWarpX1,
                      MergedRuleSet(rfs, RulesSums, RulesFFTXPromoteWarpX2),
                      RulesFFTXPromoteNT,
                      MergedRuleSet(rfs, RulesSums, RulesFFTXPromoteWarpX3) ],
        BUA, opts);
    opts.useDeref := false;
    # for debugging...
    opts.generateInitFunc := false;
#    opts.codegen := DefaultCodegen;
    opts.arrayBufModifier := "";
    opts.arrayDataModifier := "static";

    return opts;
end;

warpxConf := rec(
    defaultName := "defaultWarpXConf",
    defaultOpts := (arg) >> rec(useWarpX := true),
    confHandler := warpxOpts
);

fftx.FFTXGlobals.registerConf(warpxConf);

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:
#
# francy: Interactive Discrete Mathematics in GAP
#

#############################################################################
##
#M  Graph( <graph type> ) .
##
InstallMethod(Graph,
  "a graph type",
  true,
  [IsFrancyGraphType,
   IsFrancyGraphDefaults],
  0,
function(graphType, options)
  return MergeObjects(Objectify(FrancyGraphObjectType, rec(
    id    := GenerateID(),
    nodes := rec(),
    links := rec(),
    type  := graphType!.value,
  )), options);
end);

InstallOtherMethod(Graph,
  "a graph type",
  true,
  [IsFrancyGraphType],
  0,
function(graphType)
  return Graph(graphType, GraphDefaults);
end);

#############################################################################
##
#M  UnsetNodes( <graph> ) . . . . . removes all nodes from graph
##
InstallMethod(UnsetNodes,
  "a graph",
  true,
  [IsFrancyGraph],
  0,
function(graph)
  graph!.nodes := rec();
  return graph;
end);

#############################################################################
##
#M  UnsetNodes( <graph> ) . . . . . removes all nodes from graph
##
InstallMethod(UnsetLinks,
  "a graph",
  true,
  [IsFrancyGraph],
  0,
function(graph)
  graph!.links := rec();
  return graph;
end);

#############################################################################
##
#M  GetShape( <graph>, <string> ) . . . . . gets a node from graph
##
InstallMethod(GetShape,
  "a graph, an id",
  true,
  [IsFrancyGraph,
   IsString],
  0,
function(g, s)
  local shapes;
  shapes := GetShapes(g);
  if IsBound(shapes.(s)) then
    return shapes.(s);
  fi;
  return;
end);

#############################################################################
##
#M  GetShapes( <graph> ) . . . . . gets all nodes from graph
##
InstallMethod(GetShapes,
  "a graph",
  true,
  [IsFrancyGraph],
  0, g -> g!.nodes);

#############################################################################
##
#M  GetLink( <graph>, <string> ) . . . . . gets a link from graph
##
InstallMethod(GetLink,
  "a graph, an id",
  true,
  [IsFrancyGraph,
   IsString],
  0,
function(g, s)
  local links;
  links := GetLinks(g);
  if IsBound(links.(s)) then
    return links.(s);
  fi;
  return;
end);

#############################################################################
##
#M  GetLinks( <graph> ) . . . . . gets all links from graph
##
InstallMethod(GetLinks,
  "a graph",
  true,
  [IsFrancyGraph],
  0, g -> g!.links);

#############################################################################
##
#M  Add( <graph>, <francy object> ) . . . . . add objects to graph
##
InstallOtherMethod(Add,
  "a graph, a link",
  true,
  [IsFrancyGraph,
   IsLink],
  0,
function(graph, link)
  graph!.links!.(link!.id) := link;
  return graph;
end);

InstallOtherMethod(Add,
  "a graph, a shape",
  true,
  [IsFrancyGraph,
   IsShape],
  0,
function(graph, shape)
  graph!.nodes!.(shape!.id) := shape;
  return graph;
end);

InstallOtherMethod(Add,
  "a graph, a list of francy objects",
  true,
  [IsFrancyGraph,
   IsList],
  0,
function(graph, objects)
  local object;
  for object in objects do
    Add(graph, object);
  od;
  return graph;
end);

#############################################################################
##
#M  Remove( <graph>, <francy object> ) . . . . . remove object from graph
##
InstallOtherMethod(Remove,
  "a graph, a shape",
  true,
  [IsFrancyGraph,
   IsShape],
  0,
function(graph, shape)
  local link;
  Unbind(graph!.nodes!.(shape!.id));
  # remove also links to this object
  for link in graph!.links do
    if link!.source!.id = shape!.id or link!.target!.id = shape!.id then
      Unbind(graph!.links!.(link!.id));
    fi;
  od;
  return graph;
end);

InstallOtherMethod(Remove,
  "a graph, a link",
  true,
  [IsFrancyGraph,
   IsLink],
  0,
function(graph, link)
  Unbind(graph!.links!.(link!.id));
  return graph;
end);

InstallOtherMethod(Remove,
  "a graph, a list of francy objects",
  true,
  [IsFrancyGraph,
   IsList],
  0,
function(graph, objects)
  local object;
  for object in objects do
    Remove(graph, object);
  od;
  return graph;
end);

#############################################################################
##
#M  Shape( <shapeType>, <title>, <options> )  . .  create a Shape for a type
##
InstallMethod(Shape,
  "a shape type, a title string, a default configurations record",
  true,
  [IsShapeType,
   IsString,
   IsShapeDefaults],
  0,
function(shapeType, title, options)
  return MergeObjects(Objectify(ShapeObjectType, rec(
    id        := GenerateID(),
    type      := shapeType!.value,
    title     := title,
    callbacks := rec(),
    menus     := rec(),
    messages  := rec(),
    layer     := 0,
    parent    := ""
  )), options);
end);

InstallOtherMethod(Shape,
  "a shape type, a title string",
  true,
  [IsShapeType,
   IsString],
  0,
function(shapeType, title)
  return Shape(shapeType, title, ShapeDefaults);
end);

InstallOtherMethod(Shape,
  "a shape type",
  true,
  [IsShapeType],
  0,
function(shapeType)
  return Shape(shapeType, "", ShapeDefaults);
end);

#############################################################################
##
#M  Add( <graph>, <francy object> ) . . . . . add objects to graph
##
InstallOtherMethod(Add,
  "a shape, a menu",
  true,
  [IsShape,
   IsMenu],
  0,
function(shape, menu)
    shape!.menus!.(menu!.id) := menu;
  return shape;
end);

InstallOtherMethod(Add,
  "a shape, a callback",
  true,
  [IsShape,
   IsCallback],
  0,
function(shape, callback)
  shape!.callbacks!.(callback!.id) := callback;
  return shape;
end);

InstallOtherMethod(Add,
  "a shape, a message",
  true,
  [IsShape,
   IsFrancyMessage],
  0,
function(shape, message)
  shape!.messages!.(message!.id) := message;
  return shape;
end);

InstallOtherMethod(Add,
  "a shape, a list of objects",
  true,
  [IsShape,
   IsList],
  0,
function(shape, objects)
  local object;
  for object in objects do
    Add(shape, object);
  od;
  return shape;
end);

#############################################################################
##
#M  Remove( <graph>, <francy object> ) . . . . . remove object from graph
##
InstallOtherMethod(Remove,
  "a shape, a menu",
  true,
  [IsShape,
   IsMenu],
  0,
function(shape, menu)
  Unbind(shape!.menus!.(menu!.id));
  return shape;
end);

InstallOtherMethod(Remove,
  "a shape, a callback",
  true,
  [IsShape,
   IsCallback],
  0,
function(shape, callback)
  Unbind(shape!.callbacks!.(callback!.id));
  return shape;
end);

InstallOtherMethod(Remove,
  "a shape, a message",
  true,
  [IsShape,
   IsFrancyMessage],
  0,
function(shape, message)
  Unbind(shape!.messages!.(message!.id));
  return shape;
end);

InstallOtherMethod(Remove,
  "a shape, a list of objects",
  true,
  [IsShape,
   IsList],
  0,
function(shape, objects)
  local object;
  for object in objects do
    Remove(shape, object);
  od;
  return shape;
end);

#############################################################################
##
#M  Link( <obj1>, <obj2> )
##
InstallMethod(Link,
  "a shape, another shape, link defaults",
  true,
  [IsShape,
   IsShape,
   IsLinkDefaults],
  0,
function(source, target, options)
  return MergeObjects(Objectify(LinkObjectType, rec(
    id     := GenerateID(),
    source := source!.id,
    target := target!.id
  )), options);
end);

InstallOtherMethod(Link,
  "a shape, another shape",
  true,
  [IsShape,
   IsShape],
  0,
function(source, target)
  return Link(source, target, LinkDefaults);
end);

InstallMethod(Links,
  "a list of shape, a list of shape",
  true,
  [IsList,
   IsList,
   IsLinkDefaults],
  0,
function(source, target, options)
  local list, src, tgt;
  list := [];
  for src in source do
    for tgt in target do
      AddSet(list, Link(src, tgt, options));
    od;
  od;
  return list;
end);

InstallOtherMethod(Links,
  "a list of shape, a list of shape",
  true,
  [IsList,
   IsList],
  0,
function(source, target)
  return Links(source, target, LinkDefaults);
end);

max_stars_repo_name: LaGuer/francy

max_issues_repo_name: LaGuer/francy

max_forks_repo_name: LaGuer/francy


text:
cube := Group([(2, 3, 4, 5), (1, 2, 6, 4)]);

Print("Order(cube) = ", Order(cube), "\n");

Print("Size(Orbit(cube, 1)) = ", Size(Orbit(cube, 1)), "\n");

stab := Stabilizer(cube, 1);

Print("IsCyclic(stab) = ", IsCyclic(stab), "\n");

Print("Order(stab) = ", Order(stab), "\n");

max_stars_repo_name: fifth-postulate/group-theory-with-gap

max_issues_repo_name: fifth-postulate/group-theory-with-gap

max_forks_repo_name: fifth-postulate/group-theory-with-gap


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

# Eventually, PowerOpt should grow into a general
# loop induction variable optimization pass

ModMultOpt := code -> SubstBottomUp(code,
    [mul, @(1,Value), [imod, @r, @N]],
    e -> let(k := @(1).val.v, imod(k * @r.val, k * @N.val)));

PowerOpt := function(code)
    local powers, p, pvar, pmap;
    powers := Set(Collect(code, powmod));
    #loops := TabList( Flat(List(Collect(code, loop), l->[l.var.id, l]) ));
    #loopvars := NSFields(loops);
    for p in powers do
	if IsValue(p.args[2]) and IsVar(p.args[3]) and IsLoopIndex(p.args[3]) then
	    #Print("---", p, "---\n");
	    pvar := var.fresh("p", TInt, p.args[4].v);
	    code := SubstBottomUp(code, [powmod,
		    @(1).cond(e->e=p.args[1]),
		    @(2,Value,e->e.v=p.args[2].v),
		    @(3,var,  e->Same(e,p.args[3])),
		    @(4,Value,e->e.v=p.args[4].v)], e->pvar);

	    code := SubstBottomUp(code, @(1,loop,e->Same(e.var,p.args[3])),
		e -> decl([pvar],
		    chain(
			assign(pvar, p.args[1]),
			loop(@(1).val.var, @(1).val.range,
			    chain(@(1).val.cmd,
				assign(pvar, imod(mul(pvar, p.args[2]), p.args[4])))))));
	fi;
    od;
    return code;
end;

RangeProp := c->SubstBottomUp(c, [assign, @(1, var), @(2, var, e->IsBound(e.range))],
    e -> assign(@(1).val.setRange(@(2).val.range), @(2).val));


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

Declare(TMDCT, TIMDCT);

_DCT_CONST := 2.5;

Class(TMDCT, TaggedNonTerminal, rec(
    abbrevs := [ N -> Checked(IsInt(N), N >= 1, [N]) ] ,
    dims := self >> MDCT(self.params[1]).dims(),
    isReal := True,
    terminate := self >> MDCT(self.params[1]).terminate(),
    transpose := self >> TIMDCT(self.params[1]),
    SmallRandom := () -> Random([2, 3, 4, 6, 8, 9, 12, 16, 18, 24, 27, 32]),
    normalizedArithCost := (self) >> MDCT(self.params[1]).normalizedArithCost()
));

Class(TIMDCT, TaggedNonTerminal, rec(
    abbrevs := [ N -> Checked(IsInt(N), N >= 1, [N]) ] ,
    dims := self >> IMDCT(self.params[1]).dims(),
    isReal := True,
    terminate := self >> IMDCT(self.params[1]).terminate(),
    transpose := self >> TMDCT(self.params[1]),
    SmallRandom := () -> Random([2, 3, 4, 6, 8, 9, 12, 16, 18, 24, 27, 32]),
    normalizedArithCost := (self) >> IMDCT(self.params[1]).normalizedArithCost()
));

NewRulesFor(TMDCT, rec(
    TMDCT_DCT4_tSPL := rec(
        switch := false,
        applicable := (self, t) >> true,
        children := (self, t) >> let(tags := t.getTags(), n := t.params[1], [[
                                    TDCT4(n).withTags(tags),
                                    TTensorI(RowVec([1,1,1]), n, AVec, AVec).withTags(tags),
                                    TTensorI(ColVec([0,1]), n/2, AVec, AVec).withTags(tags),
                                    TCompose([TTensorI(RowVec(-1), n, AVec, AVec), TPrm(J(n)), TTensorI(RowVec(1), n, AVec, AVec)]).withTags(tags),
                                    TTensorI(ColVec([-1,0]), n/2, AVec, AVec).withTags(tags)
                                 ]]),
        apply := (self, t, C, Nonterms) >> C[1] * C[2] * DirectSum(C[3], C[4], C[5])
    )
));

NewRulesFor(TIMDCT, rec(
    TIMDCT_TMDCT_tSPL := rec(
        switch := false,
        applicable := (self, t) >> true,
        children := (self, t) >> [[ TMDCT(t.params[1]).withTags(t.getTags()) ]],
        apply := (self, t, C, Nonterms) >> C[1].transpose()
    )
));


text:
# Here . and , print and read an integer, not a character
Brainfuck := function(prog)
  local pointer, stack, leftcells, rightcells, instr, stackptr, len,
    output, input, jump, i, j, set, get;
  input := InputTextUser();
  output := OutputTextUser();
  instr := 1;
  pointer := 0;
  leftcells := [ ];
  rightcells := [ ];
  stack := [ ];
  stackptr := 0;
  len := Length(prog);
  jump := [ ];

  get := function()
    local p;
    if pointer >= 0 then
      p := pointer + 1;
      if IsBound(rightcells[p]) then
        return rightcells[p];
      else
        return 0;
      fi;
    else
      p := -pointer;
      if IsBound(leftcells[p]) then
        return leftcells[p];
      else
        return 0;
      fi;
    fi;
  end;

  set := function(value)
    local p;
    if pointer >= 0 then
      p := pointer + 1;
      if value = 0 then
        Unbind(rightcells[p]);
      else
        rightcells[p] := value;
      fi;
    else
      p := -pointer;
      if value = 0 then
        Unbind(leftcells[p]);
      else
        leftcells[p] := value;
      fi;
    fi;
  end;

  # find jumps for faster execution
  for i in [1 .. len] do
    if prog[i] = '[' then
      stackptr := stackptr + 1;
      stack[stackptr] := i;
    elif prog[i] = ']' then
      j := stack[stackptr];
      stackptr := stackptr - 1;
      jump[i] := j;
      jump[j] := i;
    fi;
  od;

  while instr <= len do
    c := prog[instr];
    if c = '<' then
      pointer := pointer - 1;
    elif c = '>' then
      pointer := pointer + 1;
    elif c = '+' then
      set(get() + 1);
    elif c = '-' then
      set(get() - 1);
    elif c = '.' then
      WriteLine(output, String(get()));
    elif c = ',' then
      set(Int(Chomp(ReadLine(input))));
    elif c = '[' then
      if get() = 0 then
        instr := jump[instr];
      fi;
    elif c = ']' then
      if get() <> 0 then
        instr := jump[instr];
      fi;
    fi;
    instr := instr + 1;
  od;
  CloseStream(input);
  CloseStream(output);
  # for debugging purposes, return last state
  return [leftcells, rightcells, pointer];
end;

# An addition
Brainfuck("+++.<+++++.[->+<]>.");
# 3
# 5
# 8


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

Declare(GathMem);
Declare(ScatMem);

Declare(MultiBufISum);
Declare(MultiBufISumFinal);
Declare(MemISum);
Declare(R2Sum);

Declare(MultiBufDistSum);

Class(FDataOfs_mbuf, FDataOfs);
Class(RemoteData, Data, rec(
    new := (self, var, altbuf, value, ofs, spl) >> Checked(IsVar(var), IsSPL(spl), SPL(WithBases(self, rec(
           var:=var,
           altbuf:=altbuf,
           value:=value,
           ofs := ofs,
           _children:=[spl],
           dimensions := spl.dimensions)))),
    #print := (self) >> Print(DarkRedStr(self.name), "(", self.var, ", ", self.len, ", ", self.ofs, ")")

));

# Used to mark BBs which have RemoteDataUnrolled
Class(RemoteDataInit, BB, rec(
    doNotMarkBB := true
));

Class(RemoteDataUnrolled, RemoteData);
Class(RemoteDataNoBody, RemoteData);

#F GathMem(func, pkSize)
#F Explicit Gather from memory (like DMA)
Class(GathMem, BaseMat, SumsBase, rec(
    sums := self >> self,
    isReal := self >> true,
    dims := self >> self.dimensions,
    needInterleavedLeft := self >> false,
    needInterleavedRight := self >> false,
    cannotChangeDataFormat := self >> true,
    totallyCannotChangeDataFormat := self >> true,
    #-----------------------------------------------------------------------
    rChildren := self >> [self.func, self.pkSize],
    rSetChild := rSetChildFields("func", "pkSize"),
    #-----------------------------------------------------------------------
    new := (self, func, pkSize) >> SPL(WithBases(self,
        rec(func       := FF(func),
            pkSize     := pkSize,
            dimensions := [pkSize*func.domain(), pkSize*func.range()]
            ))),
    #-----------------------------------------------------------------------
    area := self >> self.pkSize * self.func.domain(),

    transpose := self >> ScatMem(self.func, self.pkSize),
    #-----------------------------------------------------------------------
    print := (self,i,is) >> Print(self.name, "(", self.func, ", ", self.pkSize, ")"),
    #-----------------------------------------------------------------------
    toAMat := self >>
          let(pkSize   := self.pkSize,
              n        := pkSize*self.func.domain(),
              N        := pkSize*self.func.range(),
              func     := fTensor(self.func, fId(pkSize)).lambda(),
              AMatMat(List([0..n-1], row -> BasisVec(N, func.at(row).ev())))
          )
));

#F ScatMem(func, pkSize)
#F Explicit Scatter to memory (like DMA)
Class(ScatMem, BaseMat, rec(
    sums := self >> self,
    dims := self >> self.dimensions,
    isReal := self >> true,
    needInterleavedLeft := self >> false,
    needInterleavedRight := self >> false,
    cannotChangeDataFormat := self >> true,
    totallyCannotChangeDataFormat := self >> true,
    area := self >> self.transpose().area(),
    toAMat := self >> TransposedAMat(self.transpose().toAMat()),
    #-----------------------------------------------------------------------
    rChildren := self >> [self.func, self.pkSize],
    rSetChild := rSetChildFields("func", "pkSize"),
    #-----------------------------------------------------------------------
    new := (self, func, pkSize) >> SPL(WithBases(self,
        rec(func       := FF(func),
            pkSize     := pkSize,
            dimensions := [pkSize*func.range(), pkSize*func.domain()]
            ))),
    #-----------------------------------------------------------------------
    transpose := self >> GathMem(self.func, self.pkSize),
    #-----------------------------------------------------------------------
    print := (self,i,is) >> Print(self.name, "(", self.func, ", ", self.pkSize, ")"),
));

Class(GathMemDummy, GathMem);
Class(ScatMemDummy, ScatMem);

#F ==========================================================================
#F MultiBufSum(<var>, <domain>, <scat>, <spl>, <gath>)
#F - Like ISum but makes multibuffered loop in the code
#F ==========================================================================

Class(MultiBufISum, ISum, rec(
    doNotMarkBB := true,
    cannotChangeDataFormat := self >> true, # Because ScatMem/GathMem (hidden) cannot change data format
    #needSeparateVRC := self >> true,

    new := meth(self, var, domain, scatmem, expr, gathmem)
        local res;
        Constraint(IsSPL(expr));
        # if domain is an integer (not symbolic) it must be non-zero
        Constraint(not IsInt(domain) or domain > 0);
        res := SPL(WithBases(self, rec(
               var := var,
               domain := domain,
               scatmem := scatmem,
               _children := [expr],
               gathmem := gathmem
        )));
        res.dimensions := expr.dims()*domain;
        return res;
    end,

    rChildren := self >> [self.scatmem, self._children[1], self.gathmem],

    rSetChild := meth(self, n, what)
       if n=1 then self.scatmem := what;
       elif n=2 then self._children[1] := what;
       elif n=3 then self.gathmem := what;
       fi;
    end,

    from_rChildren := (self, rch) >> ObjId(self)(self.var, self.domain, rch[1], rch[2], rch[3]),

    at := (self, u) >> SubstVars(Copy(self.scatmem*self._children[1]*self.gathmem), rec((self.var.id):=u)),

    dims := (self) >> self._children[1].dims()*self.domain,
    rng := (self) >> self.scatmem.rng(), # Since this is hidden
    dmn := (self) >> self.gathmem.dmn(), # Since this is hidden

    print := meth(self, indent, indentStep)
        local expr, scatmem, gathmem;
        expr := self._children[1];
        scatmem := self.scatmem;
        gathmem := self.gathmem;

        Print(self.name, "(", self.var, ", ", self.domain);
        self._newline(indent + indentStep);
        SPLOps.Print(scatmem, indent+indentStep, indentStep);

        self._newline(indent + indentStep);
        SPLOps.Print(expr, indent+indentStep, indentStep);

        self._newline(indent + indentStep);
        SPLOps.Print(gathmem, indent+indentStep, indentStep);
        self._newline(indent);
        Print(")");
    end

));

#NOTE: this probably needs a needSeparateVRC. Check and add.
Class(MultiBufDistSum, DistSum, rec(
    new := meth(self, var, domain, scatmem, expr, gathmem)
        local res;
        Constraint(IsSPL(expr));
        # if domain is an integer (not symbolic) it must be non-zero
        Constraint(not IsInt(domain) or domain > 0);
        var.isParallelLoopIndex := true;
        res := SPL(WithBases(self, rec(
               var := var,
               domain := domain,
               scatmem := scatmem,
               _children := [expr],
               gathmem := gathmem
        )));
        res.dimensions := expr.dims()*domain;
        return res;
    end,

    rChildren := self >> [self.scatmem, self._children[1], self.gathmem],

    rSetChild := meth(self, n, what)
       if n=1 then self.scatmem := what;
       elif n=2 then self._children[1] := what;
       elif n=3 then self.gathmem := what;
       fi;
    end,

    from_rChildren := (self, rch) >> ObjId(self)(self.var, self.domain, rch[1], rch[2], rch[3]),

    at := (self, u) >> SubstVars(Copy(self.scatmem*self._children[1]*self.gathmem), rec((self.var.id):=u)),

    dims := (self) >> self._children[1].dims()*self.domain,

    print := meth(self, indent, indentStep)
        local expr, scatmem, gathmem;
        expr := self._children[1];
        scatmem := self.scatmem;
        gathmem := self.gathmem;

        Print(self.name, "(", self.var, ", ", self.domain);
        self._newline(indent + indentStep);
        Print(scatmem);

        self._newline(indent + indentStep);
        SPLOps.Print(expr, indent+indentStep, indentStep); #, ", ", self.nt_maps);

        self._newline(indent + indentStep);
        Print(gathmem);
        self._newline(indent);
        Print(")");
    end

));

Class(MultiBufISumFinal, MultiBufISum);
Class(MemISum, MultiBufISum);
Class(MemISumFinal, MemISum);

Class(R2Sum, ISum, rec(
    doNotMarkBB := true,
    cannotChangeDataFormat := self >> true, # Because ScatMem/GathMem (hidden) cannot change data format
    #needSeparateVRC := self >> true,

    new := meth(self, var1, domain1, var2, domain2, expr)
        local res;
        Constraint(IsSPL(expr));
        # if domain is an integer (not symbolic) it must be non-zero
        Constraint(not IsInt(domain1) or domain1 > 0);
        Constraint(not IsInt(domain2) or domain2 > 0);
        res := SPL(WithBases(self, rec(
               var1 := var1,
               domain1 := domain1,
               var2 := var2,
               domain2 := domain2,
               _children := [expr]
        )));
        res.dimensions := expr.dims()*domain1*domain2;
        return res;
    end,

    rChildren := self >> [self._children[1]],

    rSetChild := meth(self, n, what)
       if n=1 then self._children[1]  := what;
       fi;
    end,

    from_rChildren := (self, rch) >> ObjId(self)(self.var1, self.domain1, self.var2, self.domain2, rch[1]),

    at := (self, u) >> SubstVars(Copy(self.scatmem*self._children[1]*self.gathmem), rec((self.var.id):=u)),

    dims := (self) >> self._children[1].dims()*self.domain1*self.domain2,

    #rng := (self) >> self.scatmem.rng(), # Since this is hidden
    #dmn := (self) >> self.gathmem.dmn(), # Since this is hidden

    print := meth(self, i, is)
        local expr, scatmem, gathmem;
        expr := self._children[1];
        #scatmem := self.scatmem;
        #gathmem := self.gathmem;

        Print(self.name, "(", self.var1, ", ", self.domain1, ", ", self.var2, ", ", self.domain2);
        #self._newline(i + is);
        #SPLOps.Print(scatmem, i+is, is);

        self._newline(i + is);
        SPLOps.Print(expr, i+is, is);

        #self._newline(i + is);
        #SPLOps.Print(gathmem, i+is, is);
        self._newline(i);
        Print(")");
    end

));


text:
InstallGlobalFunction(MitM_ATPToRec,
function(atp)
    local i, res;

    res := rec();

    for i in [1,3..Length(MitM_Content(atp))-1] do
        res.( MitM_Name(MitM_Content(atp)[i]) ) :=
            EvalString(MitM_OMRecToGAPNC(MitM_Content(atp)[i+1]).result);
    od;
    return res;
end);

InstallGlobalFunction(MitM_RecToATP,
function(r)
    return Objectify(MitM_OMRecType,
                     rec( name := "OMATP"
                        , content := Concatenation(
                                List( NamesOfComponents(r)
                                    , n -> [ OMS("scscp1", n)
                                           , MitM_GAPToOMRec(r.(n)) ] ) ) ));
end);

InstallGlobalFunction(OMATP,
function(r)
    return Objectify(MitM_OMRecType,
                     rec( name := "OMATP"
                        , content := Concatenation(
                                List( NamesOfComponents(r)
                                    , n -> [ OMS("scscp1", n)
                                           , r.(n) ] ) ) ));
end);

InstallGlobalFunction(OMOBJ,
function(obj)
    return Objectify( MitM_OMRecType
                    , rec( name := "OMOBJ"
                         , attributes := rec( version := "2.0" )
                         , content := [obj] ) );
end);

InstallGlobalFunction(OMA,
function(oms, args...)
    return Objectify( MitM_OMRecType
                    , rec( name := "OMA"
                         , content := Concatenation( [ oms ], args ) ) );
end);

InstallGlobalFunction(OMS,
function(args...)
    local res;

    res := rec( name := "OMS"
              , attributes := rec( ) );

    if Length(args) = 2 then
        res.attributes.cd := args[1];
        res.attributes.name := args[2];
    elif Length(args) = 3 then
        res.attributes.cdbase := args[1];
        res.attributes.cd := args[2];
        res.attributes.name := args[3];
    else
        return fail;
    fi;
    return Objectify(MitM_OMRecType, res);
end);

InstallGlobalFunction(MitM_SimpleOMS,
obj_name -> OMS(MitM_cdbase, "lib", obj_name));

InstallGlobalFunction(OMATTR,
function(attr, content)
    return Objectify( MitM_OMRecType
                    , rec( name := "OMATTR"
                         , content := [ MitM_RecToATP(attr)
                                      , content ] ) );
end);

InstallGlobalFunction(OMSTR,
function(string)
    if IsEmptyString(string) then
        return Objectify( MitM_OMRecType
                        , rec( name := "OMSTR"
                             , content := [ ] ) );
    else
        return Objectify( MitM_OMRecType
                        , rec( name := "OMSTR"
                             , content := [ string ] ) );
    fi;
end);

InstallGlobalFunction(OMI,
function(int)
    return Objectify( MitM_OMRecType
                    , rec( name := "OMI"
                         , content := [ String(int) ] ) );
end);

InstallGlobalFunction(OMF,
function(float)
    return Objectify( MitM_OMRecType
                    , rec( name := "OMF"
                         , attributes := rec( dec := String(float) ) ) );
end);

InstallGlobalFunction(OME,
function(oms, content)
    return Objectify( MitM_OMRecType
                    , rec( name := "OME"
                         , content := Concatenation( [oms], content ) ) );
end);

InstallGlobalFunction(OMV,
function(name)
    return Objectify( MitM_OMRecType
                    , rec( name := "OMV"
                         , attributes := rec( name := name )
                         , content := []  ) );
end);

InstallMethod(ViewString, "for an omrec",
              [MitM_OMRecRep],
function(r)
    local attr, i, content;
    if r!.name = "OMS" then
        if IsBound(r!.attributes.cdbase) then
            return StringFormatted( "OMS(cd=\"{}\", cdbase=\"{}\", name=\"{}\")"
                                  , r!.attributes.cd, r!.attributes.cdbase, r!.attributes.name );
        else
            return StringFormatted( "OMS(cd=\"{}\", name=\"{}\")"
                                  , r!.attributes.cd, r!.attributes.name );
        fi;
    elif r!.name = "OMA" then
        return StringFormatted( "OMA({})"
                              , JoinStringsWithSeparator(List(r!.content, ViewString), ", ") );
    elif r!.name = "OMSTR" then
        if IsEmpty(MitM_Content(r)) then
            return "OMSTR(\"\")";
        else
            return StringFormatted( "OMSTR(\"{}\")", MitM_Content(r)[1] );
        fi;
    elif r!.name = "OMI" then
        return StringFormatted( "OMI({})", r!.content[1] );
    elif r!.name = "OMF" then
        # TODO: this is not really right yet
        return StringFormatted( "OMF({})", r!.attributes.dec );
    elif r!.name = "OMATP" then
        attr := [];
        for i in [1, 3 .. Length(r!.content) - 1] do
            Add(attr, Concatenation(r!.content[i]!.attributes.name,
                                    " := ", ViewString(r!.content[i+1])));
        od;
        return StringFormatted( "OMATP( rec( {} ) )",
                                JoinStringsWithSeparator(attr, ", ") );
    elif r!.name = "OMATTR" then
        content := MitM_Content(r);
        return StringFormatted( "OMATTR( {}, {} )",
                                MitM_ATPToRec(content[1]),
                                ViewString(content[2]) );
    elif r!.name = "OMOBJ" then
        return StringFormatted( "OMOBJ({})", ViewString(MitM_Content(r)[1]) );
    elif r!.name = "OME" then
        return StringFormatted( "OME({}, {})",
                                ViewString(MitM_Content(r)[1]),
                                ViewString(MitM_Content(r)[2]) );
    else
        return StringFormatted( "ViewString for {} not implemented", r!.name );
    fi;
end);

InstallMethod(ViewObj, "for an omrec",
              [MitM_OMRecRep],
function(r)
    Print(ViewString(r));
end);

InstallMethod( MitM_Tag, "for an omrec",
               [MitM_OMRecRep],
r -> r!.name);

InstallMethod(MitM_Attributes, "for an omrec",
              [MitM_OMRecRep],
function(r)
    if IsBound(r!.attributes) then
        return r!.attributes;
    else
        return rec();
    fi;
end);

InstallMethod(MitM_Name, "for an omrec",
              [MitM_OMRecRep],
function(r)
    if IsBound(r!.attributes) and IsBound(r!.attributes.name) then
        return r!.attributes.name;
    else
        return fail;
    fi;
end);

InstallMethod(MitM_CD, "for an omrec",
              [MitM_OMRecRep],
function(r)
    if r!.name = "OMS" then
        return r!.attributes.cd;
    else
        return fail;
    fi;
end);

InstallMethod(MitM_CDBase, "for an omrec",
              [MitM_OMRecRep],
function(r)
    if r!.name = "OMS" and IsBound(r!.attributes.cdbase) then
        return r!.attributes.cdbase;
    else
        return fail;
    fi;
end);

InstallMethod(MitM_Content, "for an omrec",
              [MitM_OMRecRep],
function(r)
    if IsBound(r!.content) then
        return r!.content;
    else
        return fail;
    fi;
end);

InstallMethod(\=, "for omrec and omrec",
              [MitM_OMRecRep, MitM_OMRecRep],
{x, y} -> (x!.name = y!.name and
           IsBound(x!.content) = IsBound(y!.content) and
           ((not IsBound(x!.content)) or x!.content = y!.content)));

InstallMethod(\<, "for omrec and omrec",
              [MitM_OMRecRep, MitM_OMRecRep],
function(x, y)
    if x!.name < y!.name then
        return true;
    elif x!.name = y!.name then
        if (not IsBound(x!.content)) and IsBound(y!.content) then
            return true;
        elif IsBound(x!.content) and IsBound(y!.content) then
            if x!.content < y!.content then
                return true;
            fi;
        fi;
    fi;
    return false;
end);