// // Semigroups package for GAP // Copyright (C) 2016-2022 James D. Mitchell // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see <https://www.gnu.org/licenses/>. //
#include"froidure-pin-fallback.hpp"
#include <string.h> // for size_t, memcpy
#include <algorithm> // for max #include <iostream> // for operator<<, cout, ostream #include <string> // for string
// GAP headers #include"gap_all.h"// for RNamName etc
// Semigroups package for GAP headers #include"pkg.hpp"// for HTAdd, HTValue, IsSemigroup, SEMIGROUPS #include"semigroups-debug.hpp"// for SEMIGROUPS_ASSERT
// libsemigroups headers #include"libsemigroups/report.hpp"// for REPORTER, Reporter #include"libsemigroups/timer.hpp"// for Timer
using libsemigroups::detail::Timer;
// Macros for the GAP version of the algorithm
#define INT_PLIST(plist, i) INT_INTOBJ(ELM_PLIST(plist, i)) #define INT_PLIST2(plist, i, j) INT_INTOBJ(ELM_PLIST2(plist, i, j)) #define ELM_PLIST2(plist, i, j) ELM_PLIST(ELM_PLIST(plist, i), j)
i = INT_INTOBJ(ElmPRec(data, RNamName("pos")));
nr = INT_INTOBJ(ElmPRec(data, RNamName("nr")));
if (i > nr || static_cast<size_t>(INT_INTOBJ(limit)) <= nr) {
CHANGED_BAG(parent); return data;
}
int_limit = std::max(static_cast<UInt>(INT_INTOBJ(limit)), nr + batch_size); if (report == True) {
std::cout << "#I limit = " << int_limit << std::endl;
}
Timer timer;
// get everything out of <data>
// lists of integers, objects
elts = ElmPRec(data, RNamName("elts")); // the so far enumerated elements
gens = ElmPRec(data, RNamName("gens")); // the generators
genslookup = ElmPRec(data, RNamName("genslookup")); // genslookup[i]=Position(elts, gens[i], // this is not always <i+1>!
lenindex = ElmPRec(data, RNamName("lenindex")); // lenindex[len]=position in <words> and // <elts> of first element of length <len>
first = ElmPRec(data, RNamName("first")); // elts[i]=gens[first[i]]*elts[suffix[i]], // first letter
final = ElmPRec(data, RNamName("final")); // elts[i]=elts[prefix[i]]*gens[final[i]]
prefix = ElmPRec(data, RNamName("prefix")); // see final, 0 if prefix is empty i.e. // elts[i] is a gen
suffix = ElmPRec(data, RNamName("suffix")); // see first, 0 if suffix is empty i.e. // elts[i] is a gen
// lists of lists
right = ElmPRec(data, RNamName("right")); // elts[right[i][j]]=elts[i]*gens[j], // right Cayley graph
left = ElmPRec(data, RNamName("left")); // elts[left[i][j]]=gens[j]*elts[i], left // Cayley graph
reduced = ElmPRec(data, RNamName("reduced")); // words[right[i][j]] is reduced if // reduced[i][j]=true
words = ElmPRec(data, RNamName("words")); // words[i] is a word in the gens equal to // elts[i]
rules = ElmPRec(data, RNamName("rules")); if (TNUM_OBJ(rules) == T_PLIST_EMPTY) {
RetypeBag(rules, T_PLIST_CYC);
}
// hash table
ht = ElmPRec(data, RNamName("ht"));
// current word length
len = INT_INTOBJ(ElmPRec(data, RNamName("len")));
// <elts[one]> is the mult. neutral // element if (IS_INTOBJ(ElmPRec(data, RNamName("one")))) {
one = INT_INTOBJ(ElmPRec(data, RNamName("one")));
} else {
one = 0;
}
// stop when we have applied generators to // elts[stopper_int]
stopper = ElmPRec(data, RNamName("stopper")); if (!IS_INTOBJ(stopper)) {
stopper_int = -1;
} else {
stopper_int = INT_INTOBJ(stopper);
}
if (one == 0) {
one = nr; for (k = 1; k <= nrgens; k++) {
x = ELM_PLIST(gens, k); if (!EQ(PROD(newElt, x), x)) {
one = 0; break;
} if (!EQ(PROD(x, newElt), x)) {
one = 0; break;
}
}
}
if (s != 0) {
AssPlist(suffix, nr, ELM_PLIST2(right, s, j));
} else {
AssPlist(suffix, nr, ELM_PLIST(genslookup, j));
}
// Using the output of DigraphStronglyConnectedComponents on the right and left // Cayley graphs of a semigroup, the following function calculates the strongly // connected components of the union of these two graphs.
Obj SCC_UNION_LEFT_RIGHT_CAYLEY_GRAPHS(Obj self, Obj scc1, Obj scc2) {
UInt* ptr; Int i, n, len, nr, j, k, l;
Obj comps1, id2, comps2, id, comps, seen, comp1, comp2, new_comp, x, out;
n = LEN_PLIST(ElmPRec(scc1, RNamName("id")));
if (n == 0) {
out = NEW_PREC(2);
AssPRec(out, RNamName("id"), NEW_PLIST_IMM(T_PLIST_EMPTY, 0));
AssPRec(out, RNamName("comps"), NEW_PLIST_IMM(T_PLIST_EMPTY, 0)); return out;
}
// <right> and <left> should be scc data structures for the right and left // Cayley graphs of a semigroup, as produced by // DigraphStronglyConnectedComponents. This function find the H-classes of the // semigroup from <right> and <left>. The method used is that described in: // https://www.irif.fr/~jep//PDF/Exposes/StAndrews.pdf
Obj FIND_HCLASSES(Obj self, Obj right, Obj left) {
UInt *nextpos, *sorted, *lookup, init; Int n, nrcomps, i, hindex, rindex, j, k, len;
Obj rightid, leftid, comps, buf, id, out, comp;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.