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
15 changes: 15 additions & 0 deletions BREAKING-CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,21 @@ shown and the argument list of symbolic length wait for v3. Every one of these w
| `1 * 2 * ... * n` | `UnhandledParseException` | `product(k, k, 1, n)`, which is `n!` for `n >= 1` |
| `{1, 4, 9, ..., n}` | `UnhandledParseException` | `InvalidArgumentParseException`, naming the term off the progression |

### `image` and `preimage` of a set under an expression

`image(f(x), x in A)` is `{ f(x) : x in A }` — `union({f(x)}, x in A)` — listed over a listed
`A`, an interval by interval arithmetic where `x` occurs once in `f`, and a membership object
otherwise; `preimage(f(x), x in A, Y)` is `{ x in A : f(x) in Y }`, and a set builder of that
shape is solved on evaluation where the membership is read (a listed `Y`, an interval)
([#1409](https://github.com/asc-community/AngouriMath/issues/1409), the reference's §7.3). Both
names are keywords now, and were names.

| Input | Was (2.5.0) | Now |
|---|---|---|
| `image(9 c / 5 + 32, c in (0; 100))` | `UnhandledParseException` | `(32; 212)` |
| `preimage(x^2, x in RR, {1})` | `UnhandledParseException` | `{ 1, -1 }` |
| `{ x in ZZ : x^2 in {1, 4} }` | `{ x in ZZ : x ^ 2 in { 1, 4 } }` — left as written | `{ 1, -1, 2, -2 }` |

### `binomial(n, k)` is a function

**Addition, not silent.** The binomial coefficient is a node, `Entity.Binomialf`, spelled
Expand Down
3 changes: 3 additions & 0 deletions Sources/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,9 @@ file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed
[AngouriMath/Functions/NumberTheory/ResidueClasses.cs]
file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed under MIT.\nDetails: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.\nWebsite: https://am.angouri.org.\n

[Tests/UnitTests/Core/Sets/ImageAndPreImageTest.cs]
file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed under MIT.\nDetails: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.\nWebsite: https://am.angouri.org.\n

[Tests/UnitTests/Algebra/MembershipSolvingTest.cs]
file_header_template=\nCopyright (c) 2019-2026 Angouri.\nAngouriMath is licensed under MIT.\nDetails: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.\nWebsite: https://am.angouri.org.\n

Expand Down
37 changes: 37 additions & 0 deletions Sources/AngouriMath/Convenience/MathS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6292,6 +6292,43 @@ public static class Sets
/// </summary>
public static Set Complement(Entity set, Entity universe) => universe.SetSubtract(set);

/// <summary>
/// The image of <paramref name="over"/> under the expression <paramref name="body"/>
/// in <paramref name="var"/>: <c>image(f(x), x in A)</c>, the set of the values
/// <c>f(x)</c> takes on <c>A</c> -- <c>{ f(x) : x in A }</c>, which is
/// <c>union({f(x)}, x in A)</c>. Listed over a listed set, an interval by interval
/// arithmetic where the name occurs once, and a membership object otherwise.
/// </summary>
/// <example>
/// <code>
/// Console.WriteLine("image(x^2, x in {1, 2, 3})".ToEntity().Evaled);
/// Console.WriteLine("image(9 c / 5 + 32, c in (0; 100))".ToEntity().Evaled);
/// </code>
/// Prints
/// <code>
/// { 1, 4, 9 }
/// (32; 212)
/// </code>
/// </example>
public static Set Image(Entity body, Entity var, Entity over) => new IndexedUnionf(var, over, new FiniteSet(body));

/// <summary>
/// The pre-image of <paramref name="target"/> under the expression <paramref name="body"/>
/// in <paramref name="var"/> ranging over <paramref name="over"/>:
/// <c>preimage(f(x), x in A, Y)</c> is <c>{ x in A : f(x) in Y }</c>, solved on
/// evaluation where the membership is one the statement solver reads.
/// </summary>
/// <example>
/// <code>
/// Console.WriteLine("preimage(x^2, x in RR, {1})".ToEntity().Evaled);
/// </code>
/// Prints
/// <code>
/// { 1, -1 }
/// </code>
/// </example>
public static Set PreImage(Entity body, Entity var, Entity over, Entity target) => new ConditionalSet(var, var.In(over) & body.In(target));

/// <returns>A set of all Complexes/>s</returns>
public static Set C => SpecialSet.Create(Domain.Complex);

Expand Down
2 changes: 2 additions & 0 deletions Sources/AngouriMath/Core/Antlr/AngouriMath.g
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,8 @@ atom returns[Entity value]
| 'union(' args = function_arguments ')' { Assert("union", 2, $args.list.Count); $value = $args.list[1] is Entity.Set.Inf { Element: Variable } unionRange ? MathS.Sets.IndexedUnion($args.list[0], unionRange.Element, unionRange.SupSet) : throw new InvalidArgumentParseException("union expects its second argument to say which name ranges over which set, as in union(A_i, i in I)"); }
| 'intersection(' args = function_arguments ')' { Assert("intersection", 2, $args.list.Count); $value = $args.list[1] is Entity.Set.Inf { Element: Variable } intersectionRange ? MathS.Sets.IndexedIntersection($args.list[0], intersectionRange.Element, intersectionRange.SupSet) : throw new InvalidArgumentParseException("intersection expects its second argument to say which name ranges over which set, as in intersection(A_i, i in I)"); }
| 'complement(' args = function_arguments ')' { Assert("complement", 2, $args.list.Count); $value = MathS.Sets.Complement($args.list[0], $args.list[1]); }
| 'image(' args = function_arguments ')' { Assert("image", 2, $args.list.Count); $value = $args.list[1] is Entity.Set.Inf { Element: Variable } imageRange ? MathS.Sets.Image($args.list[0], imageRange.Element, imageRange.SupSet) : throw new InvalidArgumentParseException("image expects its second argument to say which name ranges over which set, as in image(f(x), x in A)"); }
| 'preimage(' args = function_arguments ')' { Assert("preimage", 3, $args.list.Count); $value = $args.list[1] is Entity.Set.Inf { Element: Variable } preimageRange ? MathS.Sets.PreImage($args.list[0], preimageRange.Element, preimageRange.SupSet, $args.list[2]) : throw new InvalidArgumentParseException("preimage expects its second argument to say which name ranges over which set, as in preimage(f(x), x in A, Y)"); }
| 'floor(' args = function_arguments ')' { Assert("floor", 1, $args.list.Count); $value = MathS.Floor($args.list[0]); }
| 'ceil(' args = function_arguments ')' { Assert("ceil", 1, $args.list.Count); $value = MathS.Ceil($args.list[0]); }
/* SymPy's spelling, accepted so that an expression copied from there parses. Stringize
Expand Down
6 changes: 5 additions & 1 deletion Sources/AngouriMath/Core/Antlr/AngouriMath.interp

Large diffs are not rendered by default.

58 changes: 31 additions & 27 deletions Sources/AngouriMath/Core/Antlr/AngouriMath.tokens
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,16 @@ T__165=166
T__166=167
T__167=168
T__168=169
NEWLINE=170
NUMBER=171
SPECIALSET=172
BOOLEAN=173
NAN=174
VARIABLE=175
COMMENT=176
WS=177
T__169=170
T__170=171
NEWLINE=172
NUMBER=173
SPECIALSET=174
BOOLEAN=175
NAN=176
VARIABLE=177
COMMENT=178
WS=179
'!'=1
'^'=2
'-'=3
Expand Down Expand Up @@ -326,22 +328,24 @@ WS=177
'union('=149
'intersection('=150
'complement('=151
'floor('=152
'ceil('=153
'ceiling('=154
'round('=155
'min('=156
'max('=157
'argmax('=158
'argmin('=159
'gcd('=160
'lcm('=161
'binomial('=162
'trunc('=163
'erf('=164
'conjugate('=165
'domain('=166
'piecewise('=167
'apply('=168
'lambda('=169
'NaN'=174
'image('=152
'preimage('=153
'floor('=154
'ceil('=155
'ceiling('=156
'round('=157
'min('=158
'max('=159
'argmax('=160
'argmin('=161
'gcd('=162
'lcm('=163
'binomial('=164
'trunc('=165
'erf('=166
'conjugate('=167
'domain('=168
'piecewise('=169
'apply('=170
'lambda('=171
'NaN'=176
Loading
Loading