Macaulay2 / Macaulay2/M2

lift accepts matrices but liftable has no Matrix method, so there is no way to ask whether a matrix can be lifted

Open
#4,623 0 comments 0 reactions 0 assignees View on GitHub
bugs directory Core
Dominant language
Macaulay2
Stars
435
Forks
297
Avg merge
4d 20h
Merged PRs (30d)
11

Description

This issue was triaged from [`bugs/mike/0-liftable-Matrix`](https://github.com/Macaulay2/M2/blob/388c1ff0ce30d83751dea7bc7eac77fdc1305dd7/bugs/mike/0-liftable-Matrix), one of the 857 files removed from the pre-GitHub `bugs/` tree by [`d2c8d27826`](https://github.com/Macaulay2/M2/commit/d2c8d27826) and catalogued in [#36](https://github.com/Macaulay2/M2/issues/36). **The commentary below was written by Claude (Claude Opus 5, via Claude Code)**, not by @d-torrance, whose account posted it -- please weigh it accordingly.

The original file, verbatim (51 lines)

```text
Mike, we need a function "IM2_RingElement_liftable", analogous to
IM2_RingElement_lift, as well as IM2_Matrix_liftable, analogous to
IM2_Matrix_lift. Better names would be rawRingElementLiftable and
rawMatrixLiftable.

Mike, do we have en

>
> You could do it this way, until we add code to do it the right way:
>
> i1 : R = ZZ[x]
>
> o1 = R
>
> o1 : PolynomialRing
>
> i2 : f = vars R
>
> o2 = | x |
>
> i7 : liftable(Matrix,Number) := (f,k) -> try (lift(f,k); true) else
> false;
>
> i8 : liftable(f,ZZ)
>
> o8 = false
>
> i9 : liftable(f-f,ZZ)
>
> o9 = true
>
>
> On Nov 11, 2009, at 10:33 AM, René Birkner wrote:
>
> >
> > Hi,
> >
> > I would really like to have the following method for liftable:
> >
> > liftable(Matrix,ZZ) to check if a matrix is in fact a matrix over ZZ
> >
> > Right now I use my own silly code:
> >
> > liftable (Matrix,ZZ) := (M,R) -> all(flatten entries M, e -> liftable
> > (e,R))
> >
> >
> > Thanks
> > René
> >
>
```

### Where it stands today

`lift` accepts matrices; `liftable` does not. So there is no way to ask whether a matrix can be lifted
except by attempting the lift and catching the failure.

```m2
i1 : R = ZZ[x];

i2 : f = vars R

o2 = | x |

1 1
o2 : Matrix R <-- R

i3 : lift(f-f, ZZ)

o3 = 0

1 1
o3 : Matrix ZZ <-- ZZ

i4 : liftable(f-f, ZZ)
stdio:4:8:(3):[1]: error: no method found for applying liftable to:
argument 1 : 0 (of class Matrix)
argument 2 : ZZ
```

`lift` has nine methods taking a matrix — `(lift,Matrix,S,S)`, `(lift,Matrix,R,R)`,
`(lift,Matrix,R,ZZ)`, `(lift,Matrix,S,QQ)`, `(lift,Matrix,S,ZZ)` and the `MutableMatrix`
counterparts. `liftable` has fourteen methods and not one of them takes a `Matrix`; every combination
raises, including `liftable(matrix{{1/1}}, ZZ)` where the corresponding `lift` succeeds.

### A top-level implementation

The obvious definition behaves correctly on the cases that motivated the request:

```m2
liftable(Matrix, Number) := (f, k) -> try (lift(f, k); true) else false
```

giving `false` for `vars R` and `true` for `vars R - vars R` over `ZZ[x]`. The element-wise
alternative agrees:

```m2
all(flatten entries f, e -> liftable(e, k))
```

The bug file asks for something better than either — engine-level predicates, its suggested names
being `rawRingElementLiftable` and `rawMatrixLiftable`, which would answer without constructing the
lifted object. Neither exists today.

### One caveat worth knowing before implementing

A try-lift implementation would inherit [#2509](https://github.com/Macaulay2/M2/issues/2509): lifting
a real matrix to `ZZ` is broken — `lift(matrix {{1.}}, ZZ)` errors although `lift(1., ZZ)` works — so
`liftable(matrix {{1.}}, ZZ)` would answer `false` for a matrix that is plainly liftable. An
engine-side predicate would need to avoid inheriting that, or #2509 would need fixing first.

### Where this came from

Cataloguing the `bugs/` directory removed in d2c8d27826 (#36). `bugs/mike/0-liftable-Matrix` is Dan
writing to Mike in November 2009:

> Mike, we need a function "IM2_RingElement_liftable", analogous to IM2_RingElement_lift, as well as
> IM2_Matrix_liftable, analogous to IM2_Matrix_lift. Better names would be rawRingElementLiftable and
> rawMatrixLiftable.

prompted by René Birkner asking for `liftable(Matrix,ZZ)` "to check if a matrix is in fact a matrix
over ZZ", and working around its absence with the element-wise definition above.

Related but distinct: [#2103](https://github.com/Macaulay2/M2/issues/2103) asks the same question for
*modules* and notes the `lift`/`liftable` documentation is thin.

`open` · disposition `issue` · source of truth: [`bug-triage/catalog.tsv`](https://github.com/d-torrance/M2/blob/bug-triage/bug-triage/catalog.tsv)

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by locating the existing lift and liftable method definitions, including the Matrix and MutableMatrix lift methods described in the issue. Reproduce the shown Matrix examples and compare the try-lift and element-wise approaches, then add coverage for successful and failing Matrix cases while checking the real-matrix caveat from #2509.

Written by the indexing model from the issue text.

Assessment

Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.