public static bool IsSlotFiller(this AType vector, bool extended = false) { // Vector must be box array. if (!vector.IsArray) { return(false); } AType ravelVector = vector.Rank > 1 ? MonadicFunctionInstance.Ravel.Execute(vector) : vector; // Form (symbol;value) if (vector.Length != 2) { return(false); } // Symbol and value must be box. if (!ravelVector[0].IsBox || !ravelVector[0].IsBox) { return(false); } AType symbol = MonadicFunctionInstance.Disclose.Execute(ravelVector[0]); AType value = MonadicFunctionInstance.Disclose.Execute(ravelVector[1]); // calculate symbols' size int symbolLength = CalculateLength(symbol, extended); // calculate values' size int valueLength = CalculateLength(value, extended); // symbol is not a Symbol or symbol and value has same length if (symbol.Type != ATypes.ASymbol || symbolLength != valueLength) { return(false); } if (!extended) { if (!symbol.SimpleSymbolArray()) { return(false); } if (symbol.IsArray) { // If symbol is an array, it must contain distinct symbols. for (int i = 0; i < symbol.Length; i++) { for (int j = 0; j < symbol.Length; j++) { if (i != j && symbol[i].CompareTo(symbol[j]) == 0) { // Found a duplicate symbol return(false); } } } } } if (extended) { return(value.Type == ATypes.ABox || value.Type == ATypes.AFunc); } else { if (!value.IsBox) { return(false); } if (value.IsArray) { // Value is a vector. for (int i = 0; i < value.Length; i++) { if (value[i].IsPrimitiveFunction()) { return(false); } } return(true); } else { return(!value.IsPrimitiveFunction()); } } }
/// <summary> /// CASE 3: Slotfiller right argument and simple symbol left argument. /// </summary> /// <param name="symbol">Symbol to use for selecting from a slotfiller</param> /// <param name="items">Slotfiller</param> /// <returns></returns> private AType SimpleSymbolConstant2SlotFiller(AType symbol, AType items, Aplus environment) { if (!items.IsSlotFiller(true)) { throw new Error.Domain(DomainErrorText); } AType result; AType keys = MonadicFunctionInstance.Disclose.Execute(items[0], environment); AType values = MonadicFunctionInstance.Disclose.Execute(items[1], environment); if (keys.IsArray) { if (keys.Rank > 1) { keys = MonadicFunctionInstance.Ravel.Execute(keys); } if (values.Rank > 1) { values = MonadicFunctionInstance.Ravel.Execute(values); } int index = -1; // TODO: refactor, remove 'i' use the 'index' variable for (int i = 0; i < keys.Length; i++) { if (keys[i].IsBox) { throw new Error.Domain(DomainErrorText); } if (keys[i].CompareTo(symbol) == 0) { index = i; break; } } if (index == -1) { //y is a symbol and is not a member of the vector of symbol s in x. throw new Error.Index(IndexErrorText); } if (values[index].IsPrimitiveFunction() || !values[index].IsBox) { throw new Error.Domain(DomainErrorText); } result = MonadicFunctionInstance.Disclose.Execute(values[index], environment); } else { // We have only one item in the keys list if (symbol.CompareTo(keys) != 0) { throw new Error.Index(IndexErrorText); } if (values.IsPrimitiveFunction() || !values.IsBox) { throw new Error.Domain(DomainErrorText); } result = MonadicFunctionInstance.Disclose.Execute(values, environment); } return(result); }