mirror of
https://github.com/DanilaFe/abacus
synced 2026-01-25 16:15:19 +00:00
Compare commits
16 Commits
less-null
...
promotion-
| Author | SHA1 | Date | |
|---|---|---|---|
| 566831246c | |||
| ad8a0a9b2a | |||
| e430e738cf | |||
| f6e326e0f1 | |||
| 07581557c7 | |||
| 14ac9c67f4 | |||
| 0ff071e212 | |||
| 88e3bb7109 | |||
| 540e5d6099 | |||
| c9e93d87a2 | |||
| 337edd68fa | |||
| 08967fbb8f | |||
| 46f78bb2ed | |||
| 87529da15f | |||
| 7cd117dac1 | |||
| 8975bfdb99 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -24,7 +24,9 @@ hs_err_pid*
|
||||
# Custom Stuff
|
||||
# Gradle
|
||||
.gradle/*
|
||||
build/*
|
||||
**/build/*
|
||||
**/out/**
|
||||
**/.DS_Store
|
||||
|
||||
# IntelliJ
|
||||
.idea/*
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.nwapw.abacus.exception;
|
||||
|
||||
/**
|
||||
* Exception thrown when a promotion fails.
|
||||
*/
|
||||
public class PromotionException extends AbacusException {
|
||||
|
||||
/**
|
||||
* Creates a new PromotionException with the default message
|
||||
* and no additional information.
|
||||
*/
|
||||
public PromotionException() {
|
||||
this("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new PromotionException with the given additional message.
|
||||
* @param message the additional message to include with the error.
|
||||
*/
|
||||
public PromotionException(String message) {
|
||||
super("Failed to promote number instances.", message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import org.nwapw.abacus.exception.ComputationInterruptedException;
|
||||
/**
|
||||
* An interface used to represent a number.
|
||||
*/
|
||||
public abstract class NumberInterface {
|
||||
public abstract class NumberInterface implements Comparable<NumberInterface> {
|
||||
|
||||
/**
|
||||
* Check if the thread was interrupted and
|
||||
@@ -158,14 +158,6 @@ public abstract class NumberInterface {
|
||||
return intPowInternal(exponent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this number to another.
|
||||
*
|
||||
* @param number the number to compare to.
|
||||
* @return same as Integer.compare();
|
||||
*/
|
||||
public abstract int compareTo(NumberInterface number);
|
||||
|
||||
/**
|
||||
* Same as Math.signum().
|
||||
*
|
||||
|
||||
@@ -141,6 +141,7 @@ public class PluginManager {
|
||||
registeredNumberImplementations.put(name, implementation);
|
||||
interfaceImplementationNames.put(implementation.getImplementation(), name);
|
||||
interfaceImplementations.put(implementation.getImplementation(), implementation);
|
||||
cachedPi.put(implementation.getImplementation(), implementation.instanceForPi());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -218,10 +219,6 @@ public class PluginManager {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (toReturn == null) {
|
||||
toReturn = new Documentation(name, "", "", "", type);
|
||||
registerDocumentation(toReturn);
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@@ -252,14 +249,7 @@ public class PluginManager {
|
||||
* @return pi
|
||||
*/
|
||||
public NumberInterface piFor(Class<? extends NumberInterface> forClass) {
|
||||
if (cachedPi.containsKey(forClass)) return cachedPi.get(forClass);
|
||||
NumberImplementation implementation = interfaceImplementationFor(forClass);
|
||||
NumberInterface generatedPi = null;
|
||||
if (implementation != null) {
|
||||
generatedPi = implementation.instanceForPi();
|
||||
}
|
||||
cachedPi.put(forClass, generatedPi);
|
||||
return generatedPi;
|
||||
return cachedPi.get(forClass);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -693,8 +693,7 @@ public class StandardPlugin extends Plugin {
|
||||
* @param n non-negative integer.
|
||||
* @return a number of numClass with value n factorial.
|
||||
*/
|
||||
public static NumberInterface factorial(NumberImplementation implementation, int n) {
|
||||
|
||||
synchronized public static NumberInterface factorial(NumberImplementation implementation, int n) {
|
||||
if (!FACTORIAL_LISTS.containsKey(implementation)) {
|
||||
FACTORIAL_LISTS.put(implementation, new ArrayList<>());
|
||||
FACTORIAL_LISTS.get(implementation).add(implementation.instanceForString("1"));
|
||||
|
||||
@@ -68,6 +68,7 @@ class Abacus(val configuration: Configuration) {
|
||||
pluginManager.reload()
|
||||
with(mutableContext) {
|
||||
numberImplementation = pluginManager.numberImplementationFor(configuration.numberImplementation)
|
||||
?: StandardPlugin.IMPLEMENTATION_NAIVE
|
||||
clearVariables()
|
||||
clearDefinitions()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.nwapw.abacus.number
|
||||
|
||||
import org.nwapw.abacus.Abacus
|
||||
import org.nwapw.abacus.exception.PromotionException
|
||||
import org.nwapw.abacus.plugin.NumberImplementation
|
||||
import org.nwapw.abacus.plugin.PluginListener
|
||||
import org.nwapw.abacus.plugin.PluginManager
|
||||
@@ -37,21 +38,6 @@ class PromotionManager(val abacus: Abacus) : PluginListener {
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* If a path between the given implementations has already been computed, uses
|
||||
* the already calculated path. Otherwise, calls [computePathBetween] to compute a new
|
||||
* path.
|
||||
*
|
||||
* @param from the implementation to start from.
|
||||
* @param to the implementation to get to.
|
||||
* @return the resulting promotion path, or null if it is not found
|
||||
*/
|
||||
fun getPathBetween(from: NumberImplementation, to: NumberImplementation): PromotionPath? {
|
||||
return computePaths.computeIfAbsent(from to to, {
|
||||
computePathBetween(it.first, it.second)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Promote all the numbers in the list to the same number implementation, to ensure
|
||||
* they can be used with each other. Finds the highest priority implementation
|
||||
@@ -60,22 +46,32 @@ class PromotionManager(val abacus: Abacus) : PluginListener {
|
||||
* @param numbers the numbers to promote.
|
||||
* @return the resulting promotion result.
|
||||
*/
|
||||
fun promote(vararg numbers: NumberInterface): PromotionResult? {
|
||||
fun promote(vararg numbers: NumberInterface): PromotionResult {
|
||||
val pluginManager = abacus.pluginManager
|
||||
val implementations = numbers.map { pluginManager.interfaceImplementationFor(it.javaClass) }
|
||||
val highestPriority = implementations.sortedBy { it.priority }.last()
|
||||
return PromotionResult(items = numbers.map {
|
||||
if(it.javaClass == highestPriority.implementation) it
|
||||
else getPathBetween(pluginManager.interfaceImplementationFor(it.javaClass), highestPriority)
|
||||
?.promote(it) ?: return null
|
||||
else computePaths[pluginManager.interfaceImplementationFor(it.javaClass) to highestPriority]
|
||||
?.promote(it) ?: throw PromotionException()
|
||||
}.toTypedArray(), promotedTo = highestPriority)
|
||||
}
|
||||
|
||||
override fun onLoad(manager: PluginManager?) {
|
||||
override fun onLoad(manager: PluginManager) {
|
||||
val implementations = manager.allNumberImplementations.map { manager.numberImplementationFor(it) }
|
||||
for((index, value) in implementations.withIndex()){
|
||||
for(i in index until implementations.size){
|
||||
val other = implementations[i]
|
||||
|
||||
val promoteFrom = if(other.priority > value.priority) value else other
|
||||
val promoteTo = if(other.priority > value.priority) other else value
|
||||
val path = computePathBetween(promoteFrom, promoteTo)
|
||||
computePaths.put(promoteFrom to promoteTo, path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onUnload(manager: PluginManager?) {
|
||||
override fun onUnload(manager: PluginManager) {
|
||||
computePaths.clear()
|
||||
}
|
||||
|
||||
|
||||
@@ -36,15 +36,13 @@ class NumberReducer(val abacus: Abacus, context: EvaluationContext) : Reducer<Nu
|
||||
is NumberBinaryNode -> {
|
||||
val left = children[0] as NumberInterface
|
||||
val right = children[1] as NumberInterface
|
||||
val promotionResult = promotionManager.promote(left, right) ?:
|
||||
throw EvaluationException("promotion failed.")
|
||||
val promotionResult = promotionManager.promote(left, right)
|
||||
context.numberImplementation = promotionResult.promotedTo
|
||||
abacus.pluginManager.operatorFor(treeNode.operation).apply(context, *promotionResult.items)
|
||||
}
|
||||
is FunctionNode -> {
|
||||
val promotionResult = promotionManager
|
||||
.promote(*children.map { it as NumberInterface }.toTypedArray()) ?:
|
||||
throw EvaluationException("promotion failed.")
|
||||
.promote(*children.map { it as NumberInterface }.toTypedArray())
|
||||
context.numberImplementation = promotionResult.promotedTo
|
||||
abacus.pluginManager.functionFor(treeNode.callTo).apply(context, *promotionResult.items)
|
||||
}
|
||||
|
||||
@@ -361,7 +361,12 @@ public class AbacusController implements PluginListener {
|
||||
enabledPlugins.add(plugin);
|
||||
}
|
||||
PluginManager pluginManager = abacus.getPluginManager();
|
||||
functionList.addAll(manager.getAllFunctions().stream().map(name -> pluginManager.documentationFor(name, DocumentationType.FUNCTION))
|
||||
functionList.addAll(manager.getAllFunctions().stream().map(name -> {
|
||||
Documentation documentationInstance = pluginManager.documentationFor(name, DocumentationType.FUNCTION);
|
||||
if(documentationInstance == null)
|
||||
documentationInstance = new Documentation(name, "", "", "", DocumentationType.FUNCTION);
|
||||
return documentationInstance;
|
||||
})
|
||||
.collect(Collectors.toCollection(ArrayList::new)));
|
||||
functionList.addAll(manager.getAllTreeValueFunctions().stream().map(name -> pluginManager.documentationFor(name, DocumentationType.TREE_VALUE_FUNCTION))
|
||||
.collect(Collectors.toCollection(ArrayList::new)));
|
||||
|
||||
Reference in New Issue
Block a user