Split from #358 Why isn't h(i) for i in -1.0..0.0 by 0.5 sensible (especially in Axiom)? Why is the signature of BY given (for any S in SEG S) by axiom fs:=-3.5..8.0 by 2
Type: Segment(Float)axiom expand fs
Type: List(Float)axiom gs:=-3.5..8.0 by 2.0... Anonymous asked: Why is the signature of BY ... (%, Integer)->% and not (%, S)->% I think that's a good question! The definition of BY is: BY: (%, Integer) -> % ++ \spad{s by n} creates a new segment in which only every n-th ++ element is used. and the representation for Segment is: Segment(S:Type): SegmentCategory(S) with ... Rep := Record(low: S, high: S, incr: Integer) ( See seg.spad.pamphlet ) So this is how it works by design, but I think it would be quite easy to define a new type of segment that has the properties that you expect. Let's examine Segment S:So this is how it works by design, but I think it would be quite easy to define a new type of segment that has the properties that you expect. The function [1] (D,Integer) -> D from D if D has SEGCAT D2 and D2 has TYPE and SEGCAT D2 exports BY: (%, Integer) -> % ++ \spad{s by n} creates a new segment in which only every \spad{n}-th ++ element is used. and ------------------------------- Operations -------------------------------- BY : (%,Integer) -> % ?..? : (S,S) -> % convert : S -> % hi : % -> S high : % -> S incr : % -> Integer lo : % -> S low : % -> S segment : (S,S) -> % In fact, Rep := Record(low: S, high: S, incr: Integer) BY(s, r) == [lo s, hi s, r] The current implementation of axiom a:=2..10 by 2
Type: Segment(PositiveInteger?)axiom expand a
Type: List(Integer)axiom b:= a by 4
Type: Segment(PositiveInteger?)axiom expand b
Type: List(Integer)axiom c:=(2..10 by 2) by 3
Type: Segment(PositiveInteger?)axiom expand c
Type: List(Integer)The answer for (a..b by c) by d = a..b by c*d (multiplication in Integer) So This can be fixed as: BY(s,r)==(lo s, hi s, r*incr(s)) Ah, but there is more! Since SegmentExpansionCategory(S: OrderedRing, L: StreamAggregate(S)). expand: % -> L ++ expand(l..h by k) creates value of type L with elements ++ \spad{l, l+k, ... lN} where \spad{lN <= h < lN+k}. ++ For example, \spad{expand(1..5 by 2) = [1,3,5]}. Using this specification, expand a should be . However, it is
not clear what SegmentExpansionCategory(S: OrderedRing, L: StreamAggregate(S)). To require an In my opinion, there should be two versions of - one
`expand` (with`incr:Integer` ) marches through`low` to`high` every`incr` item in the segment`low..high` in any linearly ordered set (for example, one should be able to iterate through`MWF` in`MTWTFS` using`M..S by 2` ); call this*expansion by counting* - the other
`expand` (with`incr:S` , where`S` is an`OrderedAbelianMonoid` ), marches through`low` to`high` , incrementing by`incr` (via addition in`S` ) until just before out of bound; call this*expansion by adding*
Note that even when (2..10 by 2::Integer) by 4::Integer %% =[2, 10] (after expansion by counting) is not the same as: (2..10 by 2::S) by 4::S %% = [2,8] (after expansion by adding) The compiler would require the author to distinguish the two Record[low:S, high:S, incr:Union(Integer, S)] BY: (%, Union(Integer, S)) -> % BY(s,r) == r case Integer and incr(s) case Integer => [low s, high s, r*incr(s)]$Rep r case S and incr(s) case S => [low s, high s, r+incr(s)]$Rep %%one interpretation But these are "pure" compositions of the same On the other hand if we want to allow mixed segment constructions, we may need a recursive data structure to represent segments: baserep:= Record[low:S, high:S, incr:Union(Integer, S)] Rep:=Record[baserep, incr:Union(Integer, S)] The implementation of From seg.spad:: BY: (%, Integer) -> % ++ \spad{s by n} creates a new segment in which only every \spad{n}-th ++ element is used. This should be changed to: BY: (%, Integer) -> % ++ \spad{s by n} resets the increment (default being 1) of a segment s to n, ++ keeping the original bounds That would be consistent with the current behavior and implementation. Iterating `dom` is linearly ordered by lexicographical order. Thus it should be possible to increment by any element (or equivalently in any rational direction, including the vertical) in the domain. Axiom currently only allows incrementing by `Integer` which is coerced into the domain via the diagonal. Certainly this is not expansion by counting along the segment.
axiom dom:=DirectProduct(2,
Type: Typeaxiom aa:dom:=directProduct([2,
axiom bb:dom:=directProduct([10,
axiom ss:SEG dom:=aa..bb by 3
axiom expand ss
Note that the lexicographic order is not particular kind to segments, which can have infinitely many elements if allowed to increment by arbitrary elements of the domain. Axiom has Billpage wrote: So this is how it works by design, but I think it would be quite easy to define a new type of segment that has the properties that you expect. I think it is more like a summer project!
If we insist that segments are only defined over rings, then it is possible to generalize the increment specified in the BY clause as originally expected by Anonymous. spad )abbrev category SEGCAT SegmentCategory ++ Author: Stephen M. Watt ++ Date Created: December 1986 ++ Date Last Updated: June 11, spad Compiling FriCAS source code from file /var/zope2/var/LatexWiki/5339802333908862612-25px004.spad using old system compiler. SEGCAT abbreviates category SegmentCategory ------------------------------------------------------------------------ initializing NRLIB SEGCAT for SegmentCategory compiling into NRLIB SEGCAT axiom fs:=-3.5..8.0 by 2
Type: Segment(Float)axiom expand fs
Type: List(Float)axiom gs:=-3.5..8.0 by 2.0
Type: Segment(Float)axiom expand gs
Type: List(Float)But the Axiom interpreter is still not able to parse this: axiom [i for i in -1.0..0.0 by 0.5] William Sit wrote: If all we want is for The problem with axiom [i for i in expand(1.0..10.0 by 2.5)]
Type: List(Float)axiom )set mess bot on
Type: List(PositiveInteger?)axiom [i for i in 2.8]
Type: List(Float)axiom )set mess bot off The function If all we want is for BY to be defined as constructing a segment to be used with expansion by adding, all we need is to just change the signature of BY without requiring even Ring or AbelianMonoid. No, the critical thing here is to allow Segment(S:Ring): SegmentCategory(S) with if S has SetCategory then SetCategory if S has OrderedRing then SegmentExpansionCategory(S, List S) == add Rep := Record(low: S, high: S, incr: S) But this requires that S be a Ring since we need: a..b == [a,b,1$S] William Sit continued: Remember BY does not do anything other than recording info. Since OrderedAbelianMonoid is both necessary and sufficient for expand to work on segments defined by the new BY, that is, expansion by adding (ordering is needed for termination by comparing with the upper bound), the place to change is SEGXCAT (see edited version above; where I changed in situ from Ring back to Type but in SEGXCAT, I changed from OrderedRing to OrderedAbelianMonoid, I have no objection to these changes however notice in Segment where the category is introduced: if S has OrderedRing then SegmentExpansionCategory(S, List S) Thus at least in this use of SEGXCAT the differences is moot and there is no increase in generality of the domain Segment. William Sit continued: and modified the fourth line of your demo to expand gs from expand fs). Right, sorry that was just a typo. |

SEG Float is a valid constructor--anonymous, Wed, 06 Jun 2007 15:45:26 -0500 reply