Skip to content
Draft
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
6 changes: 3 additions & 3 deletions .run/Solver.run.xml → .run/Solver 24 8 8 3 3.run.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Solver" type="Application" factoryName="Application" nameIsGenerated="true">
<configuration default="false" name="Solver 24 8 8 3 3" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="org.meeuw.math.test.Solver" />
<module name="mihxil-demo" />
<option name="PROGRAM_PARAMETERS" value="24 8 8 3 3" />
<option name="PROGRAM_PARAMETERS" value="24 8 8 3 3 " />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="org.meeuw.math.test.*" />
Expand All @@ -13,4 +13,4 @@
<option name="Make" enabled="true" />
</method>
</configuration>
</component>
</component>
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

import static org.meeuw.configuration.ReflectionUtils.getDeclaredMethodHandle;

import org.meeuw.math.IntegerUtils;
import org.meeuw.math.Randomizable;
import org.meeuw.math.abstractalgebra.Cardinality;
Expand All @@ -24,9 +26,9 @@
public class PAdicIntegers implements Field<PAdicInteger>, Randomizable<PAdicInteger> {


public static final AlgebraicIntOperator LEFT_SHIFT = new AbstractAlgebraicIntOperator("left_shift", getDeclaredMethod(PAdicInteger.class, "leftShift", int.class), (e, i) -> e + "<<" + i);
public static final AlgebraicIntOperator LEFT_SHIFT = new AbstractAlgebraicIntOperator("left_shift", getDeclaredMethodHandle(PAdicInteger.class, "leftShift", int.class), (e, i) -> e + "<<" + i);

public static final AlgebraicIntOperator RIGHT_SHIFT = new AbstractAlgebraicIntOperator("right_shift", getDeclaredMethod(PAdicInteger.class, "rightShift", int.class), (e, i) -> e + ">>" + i);
public static final AlgebraicIntOperator RIGHT_SHIFT = new AbstractAlgebraicIntOperator("right_shift", getDeclaredMethodHandle(PAdicInteger.class, "rightShift", int.class), (e, i) -> e + ">>" + i);


final int base;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import lombok.SneakyThrows;
import lombok.extern.java.Log;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.*;
import java.util.*;
import java.util.function.Consumer;
Expand Down Expand Up @@ -52,10 +54,21 @@ public static Method getDeclaredMethod(Class<?> clazz, String name, Class<?>...
return clazz.getDeclaredMethod(name, params);
}

@SneakyThrows
public static MethodHandle getDeclaredMethodHandle(Class<?> clazz, String name, Class<?>... params) {
return MethodHandles.publicLookup().unreflect(clazz.getDeclaredMethod(name, params));
}


public static Method getDeclaredBinaryMethod(Class<?> clazz, String name) {
return getDeclaredMethod(clazz, name, clazz);
}

@SneakyThrows
public static MethodHandle getDeclaredBinaryMethodHandle(Class<?> clazz, String name) {
return MethodHandles.publicLookup().unreflect(getDeclaredBinaryMethod(clazz, name));
}

/**
* Borrowed from <a href="https://stackoverflow.com/questions/9797212/finding-the-nearest-common-superclass-or-superinterface-of-a-collection-of-classes">stackoverflow</a>
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package org.meeuw.math.operators;

import java.lang.invoke.MethodHandle;

import lombok.Getter;
import lombok.SneakyThrows;
import lombok.extern.java.Log;
Expand All @@ -33,13 +35,13 @@
public class AbstractAlgebraicIntOperator implements AlgebraicIntOperator {

@Getter
final Method method;
final MethodHandle method;

final BiFunction<CharSequence, CharSequence, String> stringify;

final String name;

public AbstractAlgebraicIntOperator(String name, Method method, BiFunction<CharSequence, CharSequence, String> stringify) {
public AbstractAlgebraicIntOperator(String name, MethodHandle method, BiFunction<CharSequence, CharSequence, String> stringify) {
this.name = name;
this.method = method;
this.stringify = stringify;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,12 @@ default String getSymbol() {

@Override
default <E extends AlgebraicElement<E>> Method getMethodFor(E e) {
try {
/* try {
return e.getClass().getMethod(getMethod().getName(), e.getStructure().getElementClass());
} catch (NoSuchMethodException nsme) {
return OperatorInterface.super.getMethodFor(e);
}
}*/
return null;
Copy link

Copilot AI Aug 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning null from getMethodFor() may cause NullPointerException in code that expects a valid Method object. This appears to be incomplete migration where the method signature still returns Method but the implementation has been changed to accommodate MethodHandle.

Copilot uses AI. Check for mistakes.
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package org.meeuw.math.operators;

import java.lang.invoke.MethodHandle;

import lombok.SneakyThrows;

import java.lang.reflect.InvocationTargetException;
Expand Down Expand Up @@ -46,21 +48,16 @@ default String getSymbol() {

@SuppressWarnings("unchecked")
@SneakyThrows
static <E extends AlgebraicElement<E>> E apply(AlgebraicIntOperator operator, Method method, E e, int i) {
static <E extends AlgebraicElement<E>> E apply(AlgebraicIntOperator operator, MethodHandle method, E e, int i) {
try {
return (E) method.invoke(e, i);
} catch (IllegalArgumentException iae) {
try {
// It is possible that the operation is defined, but the class does not extend the correct class
// e.g. an odd integer implements negation, but it is not an additive group (negation is possible inside the algebra, but addition itself isn't).
return (E) e.getClass().getMethod(method.getName(), int.class).invoke(e, i);
} catch (NoSuchMethodException noSuchMethodError) {
throw new NoSuchOperatorException("No operation " + operator + " found on " + e, noSuchMethodError);
} catch (InvocationTargetException ex) {
throw ex.getCause();
}
} catch (InvocationTargetException ex) {
throw ex.getCause();

// It is possible that the operation is defined, but the class does not extend the correct class
// e.g. an odd integer implements negation, but it is not an additive group (negation is possible inside the algebra, but addition itself isn't).
//return (E) e.getClass().getMethod(method.getName(), int.class).invoke(e, i);
throw iae;

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@
import lombok.Getter;
import lombok.SneakyThrows;

import java.lang.invoke.MethodHandle;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.function.BinaryOperator;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.meeuw.math.abstractalgebra.*;
import org.meeuw.math.exceptions.InvalidAlgebraicResult;
import org.meeuw.math.exceptions.NoSuchOperatorException;

import static org.meeuw.configuration.ReflectionUtils.getDeclaredBinaryMethod;
import static org.meeuw.configuration.ReflectionUtils.getDeclaredMethod;
import static org.meeuw.configuration.ReflectionUtils.getDeclaredBinaryMethodHandle;
import static org.meeuw.configuration.ReflectionUtils.getDeclaredMethodHandle;

/**
* The basic operations of arithmetic
Expand All @@ -42,8 +42,8 @@ public enum BasicAlgebraicBinaryOperator implements AlgebraicBinaryOperator {
* @see MagmaElement#operate(MagmaElement)
*/
OPERATION(
getDeclaredBinaryMethod(MagmaElement.class, "operate"), "*",
getDeclaredMethod(Group.class, "unity"),
getDeclaredBinaryMethodHandle(MagmaElement.class, "operate"), "*",
getDeclaredMethodHandle(Group.class, "unity"),
BasicAlgebraicUnaryOperator.INVERSION,
2
),
Expand All @@ -52,8 +52,8 @@ public enum BasicAlgebraicBinaryOperator implements AlgebraicBinaryOperator {
* @see AdditiveSemiGroupElement#plus(AdditiveSemiGroupElement)
*/
ADDITION(
getDeclaredBinaryMethod(AdditiveSemiGroupElement.class, "plus"), "+",
getDeclaredMethod(AdditiveMonoid.class, "zero"),
getDeclaredBinaryMethodHandle(AdditiveSemiGroupElement.class, "plus"), "+",
getDeclaredMethodHandle(AdditiveMonoid.class, "zero"),
BasicAlgebraicUnaryOperator.NEGATION,
2
),
Expand All @@ -62,7 +62,7 @@ public enum BasicAlgebraicBinaryOperator implements AlgebraicBinaryOperator {
* @see AdditiveGroupElement#minus(AdditiveGroupElement)
*/
SUBTRACTION(
getDeclaredBinaryMethod(AdditiveGroupElement.class, "minus"), "-",
getDeclaredBinaryMethodHandle(AdditiveGroupElement.class, "minus"), "-",
ADDITION.unity,
ADDITION.inverse,
2
Expand All @@ -73,8 +73,8 @@ public enum BasicAlgebraicBinaryOperator implements AlgebraicBinaryOperator {
* @see MultiplicativeSemiGroupElement#times(MultiplicativeSemiGroupElement)
*/
MULTIPLICATION(
getDeclaredBinaryMethod(MultiplicativeSemiGroupElement.class, "times"), "⋅",
getDeclaredMethod(MultiplicativeMonoid.class, "one"),
getDeclaredBinaryMethodHandle(MultiplicativeSemiGroupElement.class, "times"), "⋅",
getDeclaredMethodHandle(MultiplicativeMonoid.class, "one"),
BasicAlgebraicUnaryOperator.RECIPROCAL,
3
),
Expand All @@ -83,7 +83,7 @@ public enum BasicAlgebraicBinaryOperator implements AlgebraicBinaryOperator {
* @see MultiplicativeGroupElement#dividedBy(MultiplicativeGroupElement)
*/
DIVISION(
getDeclaredBinaryMethod(MultiplicativeGroupElement.class, "dividedBy"), "/",
getDeclaredBinaryMethodHandle(MultiplicativeGroupElement.class, "dividedBy"), "/",
MULTIPLICATION.unity,
MULTIPLICATION.inverse,
3
Expand All @@ -93,18 +93,18 @@ public enum BasicAlgebraicBinaryOperator implements AlgebraicBinaryOperator {
* @see CompleteFieldElement#pow(CompleteFieldElement)
*/
POWER(
getDeclaredBinaryMethod(CompleteFieldElement.class, "pow"), "^",
getDeclaredBinaryMethodHandle(CompleteFieldElement.class, "pow"), "^",
MULTIPLICATION.unity,
null,
4
);


@Getter
final Method method;
final MethodHandle method;

@Getter
final Method unity;
final MethodHandle unity;

@Getter
@Nullable
Expand All @@ -119,7 +119,8 @@ public enum BasicAlgebraicBinaryOperator implements AlgebraicBinaryOperator {

final int precedence;

BasicAlgebraicBinaryOperator(Method method, String symbol, Method unity, BasicAlgebraicUnaryOperator inverse, int precedence) {
@SneakyThrows
BasicAlgebraicBinaryOperator(MethodHandle method, String symbol, MethodHandle unity, BasicAlgebraicUnaryOperator inverse, int precedence) {
this.method = method;
this.symbol = symbol;
this.stringify = (a, b) -> a + " " + symbol + " " + b;
Expand All @@ -134,12 +135,12 @@ public enum BasicAlgebraicBinaryOperator implements AlgebraicBinaryOperator {
@SneakyThrows
public <E extends AlgebraicElement<E>> E apply(E element1, E element2) {
try {
if (!method.getParameterTypes()[0].isInstance(element1)) {
/* if (!method.getParameterTypes()[0].isInstance(element1)) {
throw new NoSuchOperatorException(element1.getClass().getSimpleName() + " " + element1 + " has no operator '" + method.getName() + "'");
}
}*/
E result = (E) method.invoke(element1, element2);
if (result == null) {
throw new InvalidAlgebraicResult("" + method + "(" + element1 + ',' + element2 + ") resulted null");
throw new InvalidAlgebraicResult(method + "(" + element1 + ',' + element2 + ") resulted null");
Copy link

Copilot AI Aug 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

String concatenation with MethodHandle may not produce the expected readable output. MethodHandle.toString() typically returns internal implementation details rather than a user-friendly method description. Consider storing the method name separately or using a different approach for error messages.

Suggested change
throw new InvalidAlgebraicResult(method + "(" + element1 + ',' + element2 + ") resulted null");
throw new InvalidAlgebraicResult(symbol + "(" + element1 + ", " + element2 + ") resulted null");

Copilot uses AI. Check for mistakes.
}
return result;
} catch (InvocationTargetException ite) {
Expand Down Expand Up @@ -175,15 +176,7 @@ public <E extends AlgebraicElement<E>> E inverse(E element) {
@SuppressWarnings("unchecked")
@SneakyThrows
public <E extends AlgebraicElement<E>, S extends AlgebraicStructure<E>> E unity(S structure) {
try {
return (E) unity.invoke(structure);
} catch (IllegalAccessException e) {
throw new IllegalArgumentException(unity.getDeclaringClass().getName() + "." + unity.getName() + "(" + structure + " ): " + e.getMessage());
} catch (IllegalArgumentException iae) {
throw new NoSuchOperatorException("for unity of " + structure + ":" + iae.getMessage(), iae);
} catch (InvocationTargetException e) {
throw e.getCause();
}
return (E) unity.invoke(structure);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@
*/
package org.meeuw.math.operators;

import java.lang.invoke.MethodHandle;

import lombok.Getter;
import lombok.SneakyThrows;
import lombok.extern.java.Log;

import java.lang.reflect.Method;

import static org.meeuw.configuration.ReflectionUtils.getDeclaredMethodHandle;

import org.meeuw.math.abstractalgebra.*;
import org.meeuw.math.text.TextUtils;

Expand All @@ -38,23 +42,23 @@ public enum BasicAlgebraicIntOperator implements AlgebraicIntOperator {
* Raising to an integer power, which is defined for all {@link MultiplicativeSemiGroupElement}s.
*/
POWER(
getDeclaredMethod(MultiplicativeSemiGroupElement.class, "pow", int.class),
getDeclaredMethodHandle(MultiplicativeSemiGroupElement.class, "pow", int.class),
(s, i) -> withBracketsIfNeeded(s) + TextUtils.superscript(i)
),

/**
* Taking the n-th root of an element, which is defined for all {@link CompleteFieldElement}s.
*/
ROOT(
getDeclaredMethod(CompleteFieldElement.class, "root", int.class),
getDeclaredMethodHandle(CompleteFieldElement.class, "root", int.class),
(s, i) -> TextUtils.superscript(i) + "√" + withBracketsIfNeeded(s)
),

/**
* Taking the n-th tetration of an element.
*/
TETRATION(
getDeclaredMethod(CompleteFieldElement.class, "tetration", int.class),
getDeclaredMethodHandle(CompleteFieldElement.class, "tetration", int.class),
(s, i) -> TextUtils.superscript(i) + withBracketsIfNeeded(s)
)
;
Expand All @@ -70,11 +74,11 @@ private static boolean needsBrackets(CharSequence s) {


@Getter
final Method method;
final MethodHandle method;

final java.util.function.BiFunction<CharSequence, CharSequence, String> stringify;

BasicAlgebraicIntOperator(Method method, java.util.function.BiFunction<CharSequence, CharSequence, String> stringify) {
BasicAlgebraicIntOperator(MethodHandle method, java.util.function.BiFunction<CharSequence, CharSequence, String> stringify) {
this.method = method;
this.stringify = stringify;
}
Expand Down
Loading
Loading