Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
278 changes: 278 additions & 0 deletions lib/Wunden/BUILDING_GENERAL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
> Package adaptation: implementations load automatically with HAP. References to the original standalone files below describe their provenance.

# The building for SL(n, Z[1/p])

[building_general.gi](building_general.gi) generalizes the construction to any
integer $n\geq2$ and prime $p$. It returns a `HapNonFreeResolution`, with the
same row-lattice convention and HAP interface as [original rank-three test fixture](../../tst/Wunden/building_sl3_reference.g).
Neither `buildin.g` nor `CONSTRUCTION.md` is changed by this implementation.

```gap
LoadPackage("hap");
B := BruhatTitsBuildingSL(6,2);;
IsHapNonFreeResolution(B); # true
List([0..5],B!.dimension); # [6,15,20,15,6,1]
Length(B); # 5
H := B!.stabilizer(2,1);; # stabilizer of the first triangle
GeneratorsOfGroup(H);
IdentityMat(6) in H; # true
B!.boundary(2,1);
B!.cellRepresentatives[3][1]; # its three vertex lattice bases
```

The files can be loaded together. They use different constructor and attribute
names. For the old case, call `BruhatTitsBuildingSL(3,2)`; its cell numbering,
orientations, boundaries, and stabilizer subgroups agree with the original.
The generating lists need not be identical.

## 1. The fundamental chamber

The vertices are homothety classes of full-rank $\mathbb{Z}_p$-lattices in
$\mathbb{Q}_p^n$. A row basis $a$ represents $L(a)=\mathbb{Z}_p^n a$.
Choose

$$
a_i=\operatorname{diag}(\underbrace{1,\ldots,1}_{n-i},
\underbrace{p,\ldots,p}_{i}),
\qquad 0\leq i<n.
$$

Their lattices satisfy

$$
pL_0\subsetneq L_{n-1}\subsetneq\cdots\subsetneq L_1\subsetneq L_0.
$$

The vertices $v_i=[L_i]$ form an $(n-1)$-simplex, a fundamental chamber for
$G=\mathrm{SL}_n(\mathbb{Z}[1/p])$. Every nonempty face supplies one cell-orbit
representative. There are $\binom{n}{d+1}$ representatives of dimension $d$,
and $2^n-1$ in total. In particular, $n=6$ requires only 63 representatives.
As in the original file, these represent an infinite building, not a finite ball.

The code generates the face lists with

```gap
cells := List([1..n],k -> Combinations([1..n],k));
```

GAP index `i+1` represents mathematical vertex $v_i$. Combinations are ordered
lexicographically, and every face is oriented by increasing vertex index.

The type $v_p(\det a)\bmod n$ is preserved by $G$. Every chamber contains one
vertex of each type, so a cell stabilizer fixes all its vertices and preserves
orientation. Thus the HAP orientation function `action(d,k,g)` is always 1.

## 2. Boundaries and the HAP object

For an oriented face, the boundary is the usual alternating sum:

$$
\partial[v_{i_0},\ldots,v_{i_d}]
=\sum_{j=0}^d(-1)^j[v_{i_0},\ldots,\widehat{v_{i_j}},\ldots,v_{i_d}].
$$

Each face is already a chosen representative, so every attaching group
element is the identity, at `B!.elts[1]`. Boundary terms have HAP format
`[signedCellIndex,elementIndex]`; terms are returned in ascending face-index
order to agree with `buildin.g`. Negative input cell indices negate the boundary.

The fields `group`, `dimension`, `boundary`, `stabilizer`, `action`, `elts`,
`homotopy`, `cellRepresentatives`, and `properties` have the same meaning as in
the original construction. Stabilizers are now computed on their first use
and cached. Their generators are actual rational matrices.

HAP's left action corresponds to $g\cdot[L]=[Lg^{-1}]$ for row lattices.
The group is generated by all $I+E_{ij}$, $i\ne j$, together with
$\operatorname{diag}(p,p^{-1},1,\ldots,1)$. Conjugating elementary matrices
and taking powers gives arbitrary coefficients in $\mathbb{Z}[1/p]$.
For $n=2$, conjugation scales the off-diagonal coefficient by $p^2$;
taking the $p$th power also supplies a coefficient $1/p$.

## 3. Reducing a cell stabilizer to an integral flag stabilizer

The stabilizer of $v_i$ is $a_i^{-1}\mathrm{SL}_n(\mathbb{Z})a_i$.
A face stabilizer is the intersection of its vertex stabilizers.
Instead of asking GAP to intersect infinite matrix groups, the code rotates
the face to one containing $v_0$.

Let $r$ have entry $p$ in position $(1,n)$ and entries 1 immediately below
the diagonal; all its other entries are zero. It satisfies

$$
L_i r=L_{i+1}\quad(i<n-1),\qquad L_{n-1}r=pL_0.
$$

If the smallest vertex label in a face is $s$, right multiplication by
$r^{-s}$ subtracts $s$ from all its labels without wraparound. The normalized
face contains $v_0$, so its stabilizer is a subgroup of
$\mathrm{SL}_n(\mathbb{Z})$. If that stabilizer is $H$, the original one is
$r^{-s}Hr^s$. Although $r$ is not in $G$, it is in
$\mathrm{GL}_n(\mathbb{Z}[1/p])$ and normalizes $G$ by conjugation.

For a normalized nonzero label $j$, the lattice quotient
$L_j/pL_0$ is the prefix subspace

$$
W_{n-j}=\langle e_1,\ldots,e_{n-j}\rangle\subset\mathbb{F}_p^n.
$$

The list `cuts` contains these dimensions. A row matrix preserves $W_c$
exactly when its entries in positions $i\leq c<j$ vanish modulo $p$.
For several cuts this gives a block lower-triangular finite flag stabilizer
$P\leq\mathrm{SL}_n(\mathbb{F}_p)$. The integral stabilizer is its full preimage:

$$
H=\rho_p^{-1}(P),\qquad
\rho_p:\mathrm{SL}_n(\mathbb{Z})\longrightarrow\mathrm{SL}_n(\mathbb{F}_p).
$$

For example, for $n=3$ the first edge gives `cuts=[2]`, the second gives
`cuts=[1]`, and the chamber gives `cuts=[1,2]`. These are precisely the plane,
line, and full flag used in the original code.

## 4. Why the higher-rank stabilizer algorithm changes

The original file uses Schreier generators by enumerating a finite flag orbit.
That works well for $n=3,p=2$, where the largest orbit has 21 points. For the
full flag in dimension 6 the orbit size is

$$
\prod_{i=1}^{6}\frac{p^i-1}{p-1}.
$$

Already at $p=2$ this is 615,195. Applying every elementary generator to all
these flags would overwhelm the otherwise small chamber construction.

For $n\geq3$ the new code instead builds

$$
H=\langle\text{generators of }\Gamma_n(p),
\ \text{integer lifts of generators of }P\rangle,
\qquad \Gamma_n(p)=\ker\rho_p.
$$

This equality follows directly: any element of $H$ has the same finite image
as a word in the chosen lifts, and dividing by that word leaves an element
of the kernel. It is essential to include the kernel; the finite flag group
alone does not describe the infinite stabilizer.

### 4.1 Principal congruence generators

For $n\geq3$, the code uses the generating set in Proposition 1.10 of
[Detinko–Flannery–Hulpke, *Algorithms for arithmetic groups with the congruence
subgroup property*](https://arxiv.org/pdf/1906.10423), attributed there to
Sury–Venkataramana. Put $t_{ij}(p)=I+pE_{ij}$ and

$$
\Sigma=\{I\}\ \cup\ \{\text{coordinate transpositions}\}
\ \cup\ \{I-2E_{kk}-2E_{k+1,k+1}+E_{k+1,k}:1\leq k<n\}.
$$

The matrices $c^{-1}t_{ij}(p)c$, for $i<j$ and $c\in\Sigma$, generate
$\Gamma_n(p)$. `principalGenerators` implements this formula and removes
duplicates. The formula applies to $p=2$ as well as odd primes, but is not
used for $n=2$. Its number of candidate generators depends only on $n$.
Coordinate transpositions have determinant $-1$, which is harmless:
conjugation still preserves determinant 1 and the congruence condition.

### 4.2 Lifting the finite flag group

The finite block lower-triangular group is generated by:

- Elementary matrices $I+E_{ij}$ in the permitted positions. Their powers
provide all coefficients because the field is the prime field.
- The determinant-one diagonal torus.

The permitted positions are exactly those for which no cut satisfies
$i\leq c<j$. This includes both directions within a diagonal block and
the lower off-block entries. Elementary matrices inside each block generate
its special linear part. Adding the diagonal torus gives all possible block
determinants with total product 1.

For odd $p$, choose a primitive residue $u$ modulo $p$, and choose an integer
$v$ with $uv\equiv1\pmod{p^2}$. On coordinates $(i,n)$ the code uses the block

$$
\begin{pmatrix}u&p\\(uv-1)/p&v\end{pmatrix}.
$$

Its determinant is exactly 1, and its reduction is
$\operatorname{diag}(u,u^{-1})$. The lower off-diagonal entry is divisible by
$p$ because the inverse was computed modulo $p^2$, not just $p$.
Using these blocks for $i=1,\ldots,n-1$ generates the entire finite diagonal
torus. When $p=2$ that torus is trivial and needs no generators.

## 5. Rank two: Schreier's lemma remains explicit

For $n=2$ the chamber is an edge. Its two vertex stabilizers are conjugates
of $\mathrm{SL}_2(\mathbb{Z})$. The edge stabilizer is

$$
\{g\in\mathrm{SL}_2(\mathbb{Z}):g_{12}\equiv0\pmod p\}.
$$

It fixes the row line $\langle(1,0)\rangle$ modulo $p$. Representatives for
its $p+1$ right cosets are

$$
r_t=\begin{pmatrix}1&t\\0&1\end{pmatrix}\quad(0\leq t<p),
\qquad r_\infty=\begin{pmatrix}0&1\\-1&0\end{pmatrix}.
$$

The first rows represent the projective points $[1:t]$ and $[0:1]$.
For each representative $r$ and each elementary generator $s$, the code
identifies the projective point represented by the first row of $rs$.
If its chosen representative is $r'$, then $rs(r')^{-1}$ fixes the initial
line. Schreier's lemma says these matrices generate the whole stabilizer.
This is the same idea as in `buildin.g`, with an explicit transversal rather
than a search for new orbit points. The computation has $2(p+1)$ transitions.

## 6. Membership, caching, and size limits

`DeclareAttribute` and `InstallMethod` are used as before, now with the distinct
attribute name `BTBuildingLatticeBases`. For a rational determinant-one matrix,
membership in a cell stabilizer is tested by checking that $aga^{-1}$ is
integral for every vertex basis $a$ of the cell. Since those bases are
$p$-integral diagonal matrices, the test also implies that $g$ has entries in
$\mathbb{Z}[1/p]$.

The principal congruence generating set is computed once per building object.
Integral flag generating lists are cached by their cuts. Each requested cell
stabilizer is then conjugated, given its membership attribute, and cached.
The constructor does not enumerate finite flag orbits for $n\geq3$.

There is no hard upper bound of 6 in the code, but the number of representative
faces is exponential in $n$. The test suite exercises $2\leq n\leq6$, with
multiple primes including odd primes. Large $p$ increases integer arithmetic
costs and, in rank two, the explicit Schreier transversal size. Operations
you subsequently ask GAP to perform on infinite stabilizers may have their own
costs; an efficient constructor does not make every such operation efficient.

## 7. Validation and limits

Run:

```sh
gap -q -T -c 'LoadPackage("hap"); ReadPackage("hap", "tst/Wunden/test_building_general.g"); QUIT;'
```

For the package installation on this machine:

```sh
gap -q -T -c 'LoadPackage("hap"); ReadPackage("hap", "tst/Wunden/test_building_general.g"); QUIT;'
```

Checks cover all cell stabilizers for each tested pair, determinant and lattice
preservation, face-stabilizer inclusions, signed boundaries, boundary squared
zero, augmentation, cache reuse, and negative membership examples. They also
check finite parabolic image orders in smaller dimensions and for every tested
full chamber, and the full trace-zero image of the congruence generators modulo
$p^2$. The case $(3,2)$ is compared directly with the original file.

These finite checks supplement the generation theorem; agreement of finite
images alone would not prove equality of infinite subgroups.

As before, `homotopy=fail`: there is no explicit contracting homotopy.
Stabilizers are infinite, so HAP routines requiring finite stabilizers do not
apply directly. The construction models Moss's building $B_n(p)$, not his
larger space $Y$ involving the real symmetric space.
78 changes: 78 additions & 0 deletions lib/Wunden/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Equivariant G-complex simplification

Load HAP in a fresh GAP session and use `ReduceGComplex(L)` to return a
reduced complex. The input uses the HAP G-complex interface: `dimension`,
`boundary`, `stabilizer`, `action`, `elts`, and `group`.

The algorithm repeatedly replaces balanced stars that pass the implemented
disk-collapse criterion. `HomeomorphicToDisk` implements that criterion;
it is not a general algorithm for recognizing arbitrary topological disks.
The replacement does not construct a contracting homotopy (`homotopy = fail`).

Progress messages are off by default. Enable them with:

```gap
SetInfoLevel(InfoWunden, 1);
```

Declarations are in `decsWunden.gd`; `initWunden.gi` loads the seven modules
in dependency order.

Run the small regression suites in a fresh GAP session:

```gap
LoadPackage("hap");
ReadPackage("hap", "tst/Wunden/core.g");
ReadPackage("hap", "tst/Wunden/integration.g");
```

Optional, slower homology regressions:

```gap
ReadPackage("hap", "tst/Wunden/sl3zs.g");
ReadPackage("hap", "tst/Wunden/bianchi.g");
```

These test scripts assign global example variables; use a disposable session.
The examples are regression checks, not a proof for all input complexes.

## Bruhat--Tits buildings and restriction

```gap
LoadPackage("hap");
B := BruhatTitsBuildingSL(3, 2);;
# K must be a finite-index subgroup of B!.group.
S := RestrictNonFreeResolution(B, K);;
```

`BruhatTitsBuildingSL(n,p)` requires an integer `n >= 2` and prime `p`.
It supplies the chamber cell orbits, signed boundaries, and infinite cell
stabilizers for SL(n,Z[1/p]). Stabilizer membership is tested by preservation
of the stored lattice bases (`BTBuildingLatticeBases`). No contracting
homotopy is supplied. Routines requiring finite stabilizers do not apply.

`RestrictNonFreeResolution(R,K)` requires finite index, terminating subgroup
membership tests, and the same group-element representation for K and R.
The input must have a finite nonnegative recorded length. Infinite-index
inputs may cause enumeration not to terminate; subgroup inclusion is only
checked automatically when the ambient group is known finite.

The output includes `toOriginal`, `fromOriginal`, `restrictionCells`, and
`cosetRepresentatives`. It transports an available contracting homotopy and
preserves `fail` when none is available. Restriction may extend R!.elts and
populate caches. `RestrictionCellStabilizerData` supports exact membership
in the restricted cell stabilizers.

Run the regression suites in a disposable session:

```gap
ReadPackage("hap", "tst/Wunden/test_building_general.g");
ReadPackage("hap", "tst/Wunden/test_restrict_nonfree.g");
```

The building suite reads `building_sl3_reference.g`, a test-only copy of the
original rank-three constructor, for independent comparison. That constructor
is not loaded as part of the package implementation. The tests assign global
names and are currently run manually rather than through HAP's test runner.
Do not also read the original standalone implementation scripts in the same
session: their global assignments conflict with the package declarations.
Loading