- Timestamp:
- Aug 21, 2019 2:28:12 PM (5 years ago)
- Location:
- trunk/magnolia-basic-library/src
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/magnolia-basic-library/src/BasicCxx/DynamicArrayCxx.mg
r1454 r1576 45 45 predicate accessible ( a:A, i:Intex ) = zerointex() <= i && i < a.size; 46 46 47 /** replace current value of the element at the given index of the array. */ 47 /** Replace current value of the element at the given index of the array. 48 * Enlarge {@code a} if the new element is exactly at its end. 49 */ 48 50 procedure change ( upd a:A, obs i:Intex, obs e:E ) 49 guard (accessible(a,i) || i == getSize(a)) && getSize(a) != maximumintex() { 51 guard (accessible(a,i) || i == getSize(a)) && getSize(a) != maximumintex() 52 { var a_size = a.size; 50 53 if i == bar_getSize(a.data) 51 then call enlarge_array(a,i+oneintex()); 52 end; 53 call bar_replaceSegment(a.data,i,i+oneintex(),e); 54 if i == a.size then a.size = a.size + oneintex(); end; 54 then 55 assert i == a_size; 56 var new_s = i + i + oneintex(); 57 var new_d = bar_createArray_element(new_s,e); 58 call bar_replaceSegmentFromArray(new_d,zerointex(),a.size,a.data,zerointex()); 59 a.size = i + oneintex(); 60 a.data = new_d; 61 else 62 var new_d = a.data; 63 call bar_replaceSegment(new_d,i,i+oneintex(),e); 64 a.size = if i == a_size then a_size + oneintex() else a_size end; 65 a.data = new_d; 66 end; 55 67 }; 56 68 57 69 /** Concatenate elements of second array to the first at position {@code k} onwards, as far as possible. */ 58 70 procedure concatenate( upd a1:A, obs a2:A ) 59 guard getSize(a1) != maximumintex() && getSize(a2) != maximumintex() { 60 var a = a1.size+a2.size; 61 if( a > bar_getSize(a1.data) ) 62 then call enlarge_array (a1,a); 63 end; 64 call bar_concatenate(a1.data,a1.size,a2.data,a2.size); 65 a1.size = a; 71 guard getSize(a1) + getSize(a2) < maximumintex() 72 { var a_sum = a1.size + a2.size; 73 if a_sum <= bar_getSize(a1.data) 74 then 75 var new_d = a1.data; 76 call bar_replaceSegmentFromArray( new_d, a1.size, a_sum, a2.data, zerointex() ); 77 a1.data = new_d; 78 else 79 if a1.size == zerointex() 80 then 81 a1.data = a2.data; 82 else 83 var new_s = bar_getSize(a1.data) + bar_getSize(a2.data) + oneintex(); 84 var new_d = bar_createArray_element(new_s,bar_getElement(a1.data,zerointex())); 85 call bar_replaceSegmentFromArray(new_d,oneintex(),a1.size,a1.data,oneintex()); 86 call bar_replaceSegmentFromArray(new_d,a1.size,a_sum,a2.data,zerointex()); 87 a1.data = new_d; 88 end; 89 end; 90 a1.size = a_sum; 66 91 }; 67 92 … … 86 111 /** Deletes an element of the array. */ 87 112 procedure delete( upd a:A, obs i:Intex ) 88 guard zerointex() <= i && i < getSize(a) && getSize(a) != maximumintex() { 113 guard zerointex() <= i && i < getSize(a) && getSize(a) != maximumintex() 114 { var a_size = a.size; 115 var new_d = a.data; 89 116 // Moves element to be deleted to last position. 90 call bar_shiftSegmentGroups( a.data,a.size-i,oneintex(),oneintex(),i,a.size);117 call bar_shiftSegmentGroups(new_d,a_size-i,oneintex(),oneintex(),i,a_size); 91 118 // Effectively deletes last element. 92 a.size = a.size - oneintex(); 119 a.size = a_size - oneintex(); 120 a.data = new_d; 93 121 }; 94 122 … … 120 148 zerointex() < k && mod(a.size,k) == zerointex() && zerointex() <= i && k*i <= a.size && a.size != maximumintex(); 121 149 122 /** replace current value of the element at the given index of the array. */150 /** Insert value of the element at the given index of the array, pushing the remaining elements one step down. */ 123 151 procedure insert ( upd a:A, obs i:Intex, obs e:E ) 124 guard zerointex() <= i && i <= getSize(a) && getSize(a) != maximumintex() { 125 // Insert new element at the back. 126 call change(a,getSize(a),e); 127 // Rotate latter part to move into right position 128 call bar_shiftSegmentGroups(a.data,a.size-i,oneintex(),a.size-i-oneintex(),i,a.size); 129 }; 130 131 /** Replace the elements within the given bounds to the argument value @code{e}. */ 152 guard zerointex() <= i && i <= getSize(a) && getSize(a) != maximumintex() 153 { 154 var a_size = a.size + oneintex(); 155 if bar_getSize(a.data) < a_size 156 then // Needs to extend the underlying array. 157 var new_s = a_size + a_size + oneintex(); 158 var new_d = bar_createArray_element(new_s,e); 159 call bar_replaceSegmentFromArray(new_d,zerointex(),i,a.data,zerointex()); 160 call bar_replaceSegmentFromArray(new_d,i+oneintex(),a_size,a.data,i); 161 a.data = new_d; 162 else // Insert in existing array. Appends the new element and shifts the elements to place. 163 var new_d = a.data; 164 // Append new element to the end of the array. 165 call bar_replaceSegment(new_d,a.size,a_size,e); 166 // Rotate latter part to move into right position 167 call bar_shiftSegmentGroups(new_d,a_size-i,oneintex(),a_size-i-oneintex(),i,a_size); 168 a.data = new_d; 169 end; 170 a.size = a_size; 171 }; 172 173 /** Replace the elements within the given bounds {@code low .. high-1} to the argument value {@code e}. */ 132 174 procedure replaceSegment ( upd a:A, obs low:Intex, obs high:Intex, obs e:E ) 133 guard zerointex() <= low && accessible(a,high) && getSize(a) != maximumintex() { 134 call bar_replaceSegment(a.data,low,high,e); 175 guard low <= getSize(a) && getSize(a) != maximumintex() 176 { if high <= bar_getSize(a.data) 177 then 178 var new_d = a.data; 179 call bar_replaceSegment(new_d,low,high,e); 180 if a.size < high 181 then 182 a.size = high; 183 end; 184 a.data = new_d; 185 else 186 var new_d = bar_createArray_element(bar_getSize(a.data)+high,e); 187 call bar_replaceSegmentFromArray(new_d,zerointex(),low,a.data,zerointex()); 188 a.size = high; 189 a.data = new_d; 190 end; 135 191 }; 136 192 … … 139 195 */ 140 196 procedure replaceSegment ( upd a1:A, obs low:Intex, obs high:Intex, obs a2:A, obs start:Intex ) 141 guard zerointex() <= low && accessible(a1,high) && accessible(a2,start) && accessible(a2,start+high-low) 142 && getSize(a1) != maximumintex() && getSize(a2) != maximumintex() { 143 call bar_replaceSegmentFromArray(a1.data,low,high,a2.data,start); 144 }; 145 197 guard low <= getSize(a) && accessible(a2,start) && accessible(a2,start+high-low) 198 && getSize(a1) != maximumintex() && getSize(a2) != maximumintex() 199 { if high <= bar_getSize(a1.data) 200 then 201 var new_d = a1.data; 202 call bar_replaceSegmentFromArray(new_d,low,high,a2.data,start); 203 if a1.size < high 204 then 205 a1.size = high; 206 end; 207 a1.data = new_d; 208 else 209 var new_d = bar_createArray(bar_getSize(a1.data)+high); 210 call bar_replaceSegmentFromArray(new_d,zerointex(),low,a1.data,zerointex()); 211 call bar_replaceSegmentFromArray(new_d,low,high,a2.data,start); 212 a1.size = high; 213 a1.data = new_d; 214 end; 215 }; 216 146 217 /** Reverse the order of the elements within the bounds. */ 147 218 procedure reverseSegment ( upd a:A, obs low:Intex, obs high:Intex ) 148 guard zerointex() <= low && accessible(a,high) { 219 guard zerointex() <= low && accessible(a,high) 220 { 149 221 if a.size != maximumintex() 150 then call bar_reverseSegment(a.data,low,high); 222 then 223 var new_d = a.data; 224 call bar_reverseSegment(new_d,low,high); 225 a.data = new_d; 151 226 end; 152 227 }; 153 228 154 229 /** Reverse the order of the elements. */ 155 procedure reverse ( upd a:A ) { 230 procedure reverse ( upd a:A ) 231 { 156 232 if a.size != maximumintex() 157 then call bar_reverseSegment(a.data,zerointex(),a.size); 233 then 234 var new_d = a.data; 235 call bar_reverseSegment(new_d,zerointex(),a.size); 236 a.data = new_d; 158 237 end; 159 238 }; 160 239 161 240 /** Circularly shifts elements a distance @code{d} within the array. */ 162 procedure shift ( upd a:A, obs d:Intex ) { 241 procedure shift ( upd a:A, obs d:Intex ) 242 { 163 243 if a.size != maximumintex() 164 then call bar_shiftSegmentGroups(a.data,a.size,oneintex(),a.size-d%a.size,zerointex(),a.size); 165 end; 166 }; 167 168 /** Obsolete: Splits the array into segments of length {@code k}, 169 * and within each segment, circularly shifts elements a distance @code{d}. 170 */ 171 procedure shiftElements ( upd a:A, obs d:Intex, obs k:Intex ) 172 guard isSegmentIndex(a,k,oneintex()) && getSize(a) != maximumintex() { 173 assert idiv(a.size,k)*k == a.size; 174 assert isSegmentIndex(a,k,idiv(a.size,k)); 175 call bar_shiftSegmentGroups(a.data,k,oneintex(),k-d%k,zerointex(),a.size); 176 }; 177 244 then 245 var new_d = a.data; 246 call bar_shiftSegmentGroups(new_d,a.size,oneintex(),a.size-d%a.size,zerointex(),a.size); 247 a.data = new_d; 248 end; 249 }; 250 178 251 /** Circularly left shifts {@code groupsize} size groups of array elements 179 252 * within {@code segsize} size segments of array elements. 180 253 */ 181 procedure shiftSegmentGroups( upd a : A, obs segsize : Intex, obs groupsize : Intex, obs d : Intex ) { 182 call bar_shiftSegmentGroups(a.data,segsize,groupsize,d,zerointex(),a.size); 183 }; 184 185 /** Obsolete: Splits the array into segments of length {@code k}, 186 * and circularly shifts the segments a distance @code{d}. 187 */ 188 procedure shiftSegments ( upd a:A, obs d:Intex, obs k:Intex ) 189 guard isSegmentIndex(a,k,oneintex()) && getSize(a) != maximumintex() { 190 assert idiv(a.size,k)*k == a.size; 191 assert isSegmentIndex(a,k,idiv(a.size,k)); 192 call bar_shiftSegmentGroups(a.data,a.size,k,idiv(a.size,k)-d%idiv(a.size,k),zerointex(),a.size); 254 procedure shiftSegmentGroups( upd a : A, obs segsize : Intex, obs groupsize : Intex, obs d : Intex ) 255 { var new_d = a.data; 256 call bar_shiftSegmentGroups(new_d,segsize,groupsize,d,zerointex(),a.size); 257 a.data = new_d; 193 258 }; 194 259 … … 259 324 if size < maximumintex() 260 325 then 261 if a.size == maximumintex() 262 then a.data = bar_createArray(size,bar_getElement(a.data,zerointex())); 263 end; 264 call bar_mapf(a.data, a2, c, zerointex(), size); 326 var new_d = 327 if a.size == maximumintex() 328 then bar_createArray(size,bar_getElement(a.data,zerointex())) 329 else a.data 330 end; 331 call bar_mapf(new_d, a2, c, zerointex(), size); 265 332 a.size = size; 333 a.data = new_d; 266 334 else 267 335 // Assume both arrays are isotropic if their sizes are maximum. 268 336 assert size == maximumintex(); 269 337 // This is wrong if the index argument to f is not a dummy. 270 call bar_mapf(a.data, a2, c, zerointex(), oneintex()); 338 var new_d = a.data; 339 call bar_mapf(new_d, a2, c, zerointex(), oneintex()); 340 a.data = new_d; 271 341 end; 272 342 }; … … 307 377 extend boundedArrayRawCxxPrefix[ bar_simplify_renaming ]; 308 378 309 procedure scan ( upd a:A ) guard getSize(a) != maximumintex() = { 310 call bar_scan(a.data,zerointex(),a.size); 379 procedure scan ( upd a:A ) guard getSize(a) != maximumintex() 380 { var new_d = a.data; 381 call bar_scan(new_d,zerointex(),a.size); 382 a.data = new_d; 311 383 }; 312 384 } [ star => star, scan => scan, bar_scan => bar_scan ] -
trunk/magnolia-basic-library/src/BasicCxxExamples/LoopsCxxDemo.mg
r1454 r1576 14 14 15 15 16 satisfaction whileTest = {16 satisfaction whileTestCxx = { 17 17 use boundedNatural32bitCxx; 18 18 use whileLoopCxx … … 53 53 * Running whileTest, untilTest, breakTest, kaerbTest on the same arguments should yield the same results. 54 54 */ 55 satisfaction conditionalLoopTests = {55 satisfaction conditionalLoopTestsCxx = { 56 56 extend boundedNatural32bitCxx; 57 57 use singletonTuple[T=>Unit]; … … 66 66 /** Adapting the requirements to the use context */ 67 67 [ Data => Integer, Context => Unit, 68 cond => cond, body => body68 cond => cond, body => p 69 69 ] 70 70 /** Entities defined by the implementation, rename for the using context. */ … … 75 75 /** Adapting the requirements to the use context */ 76 76 [ Data => Integer, Context => Unit, 77 body => body, cond => ncond77 body => p, cond => ncond 78 78 ] 79 79 /** Entities defined by the implementation, rename for the using context. */ … … 122 122 123 123 /** Testing the for loop: Functions to double a number many times. */ 124 satisfaction countLoopTest_double = {124 satisfaction countLoopTest_doubleCxx = { 125 125 use boundedNatural32bitCxx; 126 126 use singletonTuple[T=>Unit]; … … 129 129 procedure double(upd n:Integer, obs m:Unit) { n = n+n; }; 130 130 131 /** The repeat function doubles a number n m times. */132 use countLoopCxx[Data => Integer, Context => Unit, p=> double ][counter_to_finite];131 /** The repeat m times the function {@link double} n. */ 132 use countLoopCxx[Data => Integer, Context => Unit, body => double ][counter_to_finite]; 133 133 134 134 /** Calls the repeat statement which should count up to the number m. */ … … 144 144 145 145 /** Testing the for loop: Define functions to raise a number n to the power of m. */ 146 satisfaction countLoopTest_raise = {146 satisfaction countLoopTest_raiseCxx = { 147 147 use torusInteger64bitCxx; 148 148 … … 177 177 /** Testing the for loop: Summation and product of consequtive numbers. 178 178 */ 179 satisfaction countLoopIndexedTest_productAndSum = {179 satisfaction countLoopIndexedTest_productAndSumCxx = { 180 180 use boundedInteger64bitCxx; 181 181 use singletonTuple[T=>Unit]; -
trunk/magnolia-basic-library/src/BasicCxxRaw/RepetitionCountCxxRawTest.mg
r1454 r1576 14 14 15 15 /** Testing the for loop: Functions to double a number many times. */ 16 satisfaction repetitionTest= {16 satisfaction test_repetitionCxx = { 17 17 use adHocPredicateRawInternalCxx; 18 18 use torusInteger8bitCxx[finite_to_small]; … … 24 24 /** Adapting the requires part to the use context */ 25 25 [ Data => Small, Context => Small, 26 body => q, body1 => q1, body2 => q2,26 body => q, 27 27 Counter => Integer, successorC => successor, zeroc => zero, 28 28 Integer => Integer, successor => successor, … … 39 39 /** Adapting the requires part to the use context */ 40 40 [ Data => Small, Context => Small, 41 body => r, body1 => r1, body2 => r2,41 body => r, 42 42 Counter => Integer, successorC => successor, zeroc => zero, 43 43 Integer => Integer, successor => successor, … … 109 109 * - Summation of consequtive numbers. 110 110 */ 111 program powerProductSum= {111 program test_powerProductSumCxx = { 112 112 use adHocPredicateRawInternalCxx; 113 113 use torusInteger16bitCxx; … … 136 136 137 137 /** Multiplies current value with base value. */ 138 procedure manipulateRaise(upd n:Pair, obs c : Unit, out preempt : Predicate, obs i : Integer) { n.current = n.current * n.base; }; 138 procedure manipulateRaise(upd n:Pair, obs c : Unit, out preempt : Predicate, obs i : Integer) { 139 var current = n.current * n.base; 140 n.current = current; 141 }; 139 142 140 143 procedure successor(upd i : Integer) = { i = i + one(); }; … … 145 148 /** Adapting the requires part to the use context */ 146 149 [ Data => Pair, Context => Unit, 147 body => manipulateRaise, body1 => manipulateRaise1, body2 => manipulateRaise2,150 body => manipulateRaise, 148 151 Counter => Counter, successorC => successorC, zeroc => zeroc, 149 152 Integer => Integer, successor => successor, … … 158 161 /** Adapting the requires part to the use context */ 159 162 [ Data => Integer, Context => Unit, 160 body => manipulateAdd, body1 => manipulateAdd1, body2 => manipulateAdd2,163 body => manipulateAdd, 161 164 Counter => Counter, successorC => successorC, zeroc => zeroc, 162 165 Integer => Integer, successor => successor, … … 171 174 /** Adapting the requires part to the use context */ 172 175 [ Data => Integer, Context => Unit, 173 body => manipulateMultiply, body1 => manipulateMultiply1, body2 => manipulateMultiply2,176 body => manipulateMultiply, 174 177 Counter => Counter, successorC => successorC, zeroc => zeroc, 175 178 Integer => Integer, successor => successor, -
trunk/magnolia-basic-library/src/BasicGeneral/ArrayFilterCxxDemo.mg
r1454 r1576 26 26 27 27 /** Finding specific elements in an array. */ 28 satisfaction dynamicArrayFloatCxx_findElementIndex_models_ArrayfindElementIndex = {28 satisfaction test_dynamicArrayFloatCxx_findElementIndex_models_ArrayfindElementIndexCxx = { 29 29 extend dynamicArrayFloatCxx; 30 30 use countLoopIndexedCxx … … 40 40 41 41 /** Finding elements smaller than a given value. */ 42 satisfaction dynamicArrayFloatCxx_arrayFindPropertyIndex_models_ArrayFindPropertyIndex = {42 satisfaction test_dynamicArrayFloatCxx_arrayFindPropertyIndex_models_ArrayFindPropertyIndexCxx = { 43 43 extend dynamicArrayFloatCxx; 44 44 use countLoopIndexedCxx -
trunk/magnolia-basic-library/src/BasicGeneral/IntegerOperations.mg
r1454 r1576 348 348 procedure pp_body( upd d:pp_Data, c:pp_Context ){ 349 349 assert zero() < d.n; 350 if d.n % (one()+one()) != zero() 350 var n = d.n; 351 var ret = d.ret; 352 var x = d.x; 353 if n % (one()+one()) != zero() 351 354 then 352 d.n = d.n - one();353 d.ret = star( d.ret,d.x);355 d.n = n - one(); 356 d.ret = star(ret,x); 354 357 end; 355 d.n = idiv( d.n, one()+one());358 d.n = idiv(n, one()+one()); 356 359 if d.n != zero() 357 then d.x = star( d.x, d.x);360 then d.x = star( x, x); 358 361 end; 359 362 }; 360 363 361 364 /** The predicate that must hold. */ 362 365 predicate pp_cond( d:pp_Data, c:pp_Context ) = zero() < d.n; -
trunk/magnolia-basic-library/src/Makefile
r1556 r1576 111 111 BasicCxx/FloatCxx/float32bitCxx_is_FiniteReal roundingAxioms -- -4.5 112 112 BasicCxx/FloatCxx/float32bitCxx_is_FiniteReal transitive 6.7 6.7 6.7 113 BasicCxx/FloatCxx/float80bitCxx_is_FiniteReal naturalLogarithmAxiom1 3 114 BasicCxx/FloatCxx/float80bitCxx_is_FiniteReal naturalLogarithmAxiom1 0 113 BasicCxx/FloatCxx/float80bitCxx_is_FiniteReal naturalLogarithmAxiom 114 BasicCxx/FloatCxx/float80bitCxx_is_FiniteReal naturalLogarithmPowAxiom 3 115 BasicCxx/FloatCxx/float80bitCxx_is_FiniteReal naturalLogarithmPowAxiom 1 115 116 TutorialExamples/Tutorial9Cxx/fibonacciLookuptable_provides_FibonacciCxx fibtable > fibtable.Fibtable &&\ 116 117 test `TutorialExamples/Tutorial9Cxx/fibonacciExternalCxx fib -i1 fibtable.Fibtable 27` -eq 196418 -
trunk/magnolia-basic-library/src/Mathematics/Numbers.mg
r1454 r1576 569 569 assert log(one()) == zero(); 570 570 } 571 axiom naturalLogarithm Axiom ( x:Number ) {571 axiom naturalLogarithmPowAxiom ( x:Number ) { 572 572 assert pow(e(),x) == exp(x); 573 573 } -
trunk/magnolia-basic-library/src/TutorialExamples/Tutorial0Cxx.mg
r1555 r1576 6 6 * Suffix Cxx implies that it may be possibly to compile the modules to executable C++ code. 7 7 * 8 * @author Jaakko J arvi, Magne Haveraaaen8 * @author Jaakko JÀrvi, Magne Haveraaaen 9 9 * @since 2015-03-17 10 10 */ … … 35 35 program welcomeCxx = { // Named program: suffix Cxx indicates programming language for target. 36 36 37 /** Uses the string module, with {@code concatenate} written as infix {@code *}. */37 /** Uses the string module, with {@code concatenate} and {@code createEmptyString} functions. */ 38 38 use stringCxx; 39 39 /** Uses the string module defining the latin characters, digits and more. */ -
trunk/magnolia-basic-library/src/TutorialExamples/Tutorial3Cxx.mg
r1476 r1576 17 17 imports 18 18 BasicCxx.IntegerCxx, 19 BasicCxx.FloatCxx; 19 BasicCxx.FloatCxx, 20 BasicCxx.StringCxx; 20 21 21 22 /** An implementation of 3 functions … … 61 62 }; 62 63 64 program strenging = { 65 use stringCxx; 66 use recurring 67 [ T => String, binop => concatenate ] 68 [ once => square, twice => cube, thrice => tesseract ]; 69 }; 63 70 64 71 /** Creating a simple implementation by combining implementations. … … 111 118 [ once => max1, twice => max2, thrice => max3 ]; 112 119 120 function min5 ( a:Float, b:Float, c:Float, d:Float, e:Float ) : Float 121 = min(min(min(a,b),min(b,c)),e); 122 113 123 /** Uses recurring directly on the power function. 114 124 * Notice how fast the function grows. -
trunk/magnolia-basic-library/src/TutorialExamples/Tutorial4Cxx.mg
r1454 r1576 31 31 echo 12 > i7.Integer ; cp v1.MY v2.MY 32 32 TutorialExamples/Tutorial4Cxx/gradual25integersCxx st -io1 i7.Integer -io2 v2.MY && head v2.MY i7.Integer 33 //TODOTutorialExamples/Tutorial4Cxx/gradual25integersCxx big -i1 v1.MY -i2 v1.MY 9934 //TODOTutorialExamples/Tutorial4Cxx/gradual25integersCxx big -i1 v1.MY -i2 v1.MY -- -567835 //TODO TutorialExamples/Tutorial4Cxx/gradual25integersCxx big -i1 v1.MY '<Mytype#Integer.Integer>4 20480</Mytype#Integer.Integer>6636 //TODOTutorialExamples/Tutorial4Cxx/gradual25integersCxx big -i1 v1.MY '<Mytype#Integer.Integer>4 2</Mytype#Integer.Integer>' -- -4433 TutorialExamples/Tutorial4Cxx/gradual25integersCxx big -i1 v1.MY -i2 v1.MY 99 34 TutorialExamples/Tutorial4Cxx/gradual25integersCxx big -i1 v1.MY -i2 v1.MY -- -5678 35 TutorialExamples/Tutorial4Cxx/gradual25integersCxx big -i1 v1.MY '<Mytype#Integer.Integer>4 20480</Mytype#Integer.Integer>' 66 36 TutorialExamples/Tutorial4Cxx/gradual25integersCxx big -i1 v1.MY '<Mytype#Integer.Integer>4 2</Mytype#Integer.Integer>' -- -44 37 37 * </pre> 38 38 * Note the use of "-ioN" for updatable procedure arguments. 39 * Also note that we can change the output to go directly to the terminal by using "-iN" for the argument. 39 * Also note that we can change the output to go directly to the terminal by using "-iN" for the argument 40 * in a procedure with a single update argument. 40 41 * <pre> 41 42 TutorialExamples/Tutorial4Cxx/gradual25integersCxx increase -i1 v1.MY … … 56 57 /** An implementation of types, functions, procedures and predicates. 57 58 * NB! Magnolia does not support recursion, neither directly nor indirectly. 59 * NB! There are no loop constructs in the Magnolia language, but they are provided in the library. 58 60 */ 59 61 implementation example = { … … 70 72 type Mytype = struct{ var left:T; var right:T; }; 71 73 74 /** Defining a function that creates a data value of the record type {@link Mytype} using its constructor. */ 72 75 function build (a:T, b:T) : Mytype = Mytype{ left = a, right = binop(a,b) }; 73 76 74 /** This procedure induces one function: 77 /** In Magnolia procedure induces set of functions corresponding to 78 * the same information flow as the procedure. 79 * An induced function is used and behaves exactly like a normal function. 80 * In this case, the procedure induces exactly one function: 75 81 *Â Â Â Â function increase(x : Mytype) : Mytype; 76 * An induced function works exactly as a normal function.77 82 */ 78 83 procedure increase ( upd x:Mytype ) = { 84 /* Here we access the components of the record type {@link Mytype} using the "dot" notation. */ 85 var xl = x.left; 79 86 if x.left == x.right 80 then x .left= binop(x.left,x.left);87 then xl = binop(x.left,x.left); 81 88 else skip; 82 89 end; 83 x.right = binop(x.left,x.right); 90 x.left = xl; 91 var xr = x.right; 92 x.right = binop(xl,xr); 84 93 }; 85 94 86 /** NOTE: the error message here is a compiler feature, not an error in the code. */95 /** Defining a function as a value block. */ 87 96 function bigger ( x:Mytype ) : T = { 88 97 var t:T = x.left; … … 92 101 }; 93 102 94 /** A predicate . */103 /** A predicate defined by a simple expression. */ 95 104 predicate small ( a:Mytype ) = a.left <= a.right; 96 105 … … 105 114 }; 106 115 107 /*< TODO: code temporarily removed due to a compiler error: nested function blocks are not supported correctly. 108 /** A trinary predicate. */ 116 /** A trinary predicate defined by nested value blocks. 117 * The inner block block defines a value which is used in the outer block. 118 * TODO! The Magnolia compiler does not generate correct code for an inner value block! 119 */ 109 120 predicate big ( a:Mytype, b:Mytype, c:T ) = { 110 121 var t:T = binop(a.left,b.right); … … 119 130 end && a != b; 120 131 }; 121 >*/ 132 122 133 123 134 }; -
trunk/magnolia-basic-library/src/TutorialExamples/Tutorial9Cxx.mg
r1457 r1576 13 13 * {@link fibonacciRoundingSimple}: the implementation has trimmed down the requirements to a minimum. 14 14 * - {@link fibonacciIteration}: using counted loops ("for loop") to iterate to the n'th number in O(n) steps. 15 * - {@link fibonacciLookuptable}: computes (using for loops) an array with all Fibonacci numbers representable in 64bit n umbers,16 * then looks up the the n'th Fib unacci number in the table.17 * - {@link fibonacciExternalCxx}: reads in a table of Fib unacci numbers and looks up the actual number.15 * - {@link fibonacciLookuptable}: computes (using for loops) an array with all Fibonacci numbers representable in 64bit natural numbers, 16 * then looks up the the n'th Fibonacci number in the table. 17 * - {@link fibonacciExternalCxx}: reads in a table of Fibonacci numbers and looks up the actual number. 18 18 * 19 19 * @see https://en.wikipedia.org/wiki/Fibonacci_number … … 81 81 * There are two distinct implementations: 82 82 * - {@link fibonacciRoundingFloat} which is entirely float based, even the IO, though only integral values can be used. 83 * This implementation will approximate the Fibonacci numbers when the numbers become to big to be represented exactly,84 * but it fails quite early due to representation errors in the golden ratio.83 * This implementation will approximate the Fibonacci numbers when the numbers become too big to be represented exactly, 84 * but it fails the axioms quite early due to representation errors in the golden ratio. 85 85 * - {@link fibonacciRounding} adds a conversion from (argument values) and to integers (result value) for the Fibonacci function. 86 86 * It has the same inaccuracy problems as {@link fibonacciRoundingFloat}, 87 87 * but will only return the maximum representable integer when the Fibonacci number goes out of range. 88 * The implementation {@link fibonacciRoundingSimple} is a variation of this,88 * - The implementation {@link fibonacciRoundingSimple} is a variation of {@link fibonacciRounding}, 89 89 * where the requirements have been trimmed as much as possible from using full library modules. 90 90 * … … 95 95 * since the properties of the premises are needed to prove the claim. 96 96 * - An executable claim (that we approcximate the Fibonacci function), 97 * {@link fibonacciRoundingFloat 64_provides_FibonacciCxx},98 * {@link fibonacciRounding 64_provides_FibonacciCxx} and {@link fibonacciRounding80_provides_FibonacciCxx}.97 * {@link fibonacciRoundingFloat_float64bitCxx_provides_Fibonacci}, 98 * {@link fibonacciRounding_float64bitCxx_boundedNatural64bitCxx_provides_Fibonacci} and {@link fibonacciRoundingSimple_float80bitCxx_boundedInteger65bitCxx_provides_Fibonacci}. 99 99 * These uses executable approximations (finite floats) without complete specifications for the premises, 100 100 * hence the implementations can only be tested and not proven correct. 101 * Also we should expect some approximation to the correct result for manyof the arguments.101 * We expect approximations to the correct result for all of the arguments. 102 102 * 103 103 * Run the following command to check the axioms for the first 100 Fibonacci numbers using the executable satisfactions. 104 104 * <pre> 105 for file in TutorialExamples/Tutorial9Cxx/fibonacciRounding*Cxx 105 for file in TutorialExamples/Tutorial9Cxx/fibonacciRounding*Cxx*_provides_Fibonacci 106 106 do echo $file 107 107 $file fibonacciBaseAxiom 108 for i in {0 ,1,2,3,4,5,6,7,8,9}{0,1,2,3,4,5,6,7,8,9}108 for i in {0..100} 109 109 do $file fibonacciGeneralAxiom $i || echo $i 110 110 done … … 147 147 * The inaccuracies in the representation of floating point numbers causes errors in the last digits already of {@code fib(71)}, 148 148 * Which has a value significantly below the maximum exactly representable integer in 64 bit floating point. 149 * On the other hand, we may get approximate values for large values of fib, up to {@code fib(71)==1.9068715787994046392e+307}. 150 * <pre> 151 TutorialExamples/Tutorial9Cxx/fibonacciRoundingFloat64_provides_FibonacciCxx fibonacciGeneralAxiom 71 152 TutorialExamples/Tutorial9Cxx/fibonacciRoundingFloat64_provides_FibonacciCxx integer_maximum 153 TutorialExamples/Tutorial9Cxx/fibonacciRoundingFloat64_provides_FibonacciCxx fib 71 154 TutorialExamples/Tutorial9Cxx/fibonacciRoundingFloat64_provides_FibonacciCxx fib 1472 155 * </pre> 156 */ 157 satisfaction fibonacciRoundingFloat64_provides_FibonacciCxx = 149 * On the other hand, we may get approximate values for large values of fib, up to {@code fib(1474)==4.9922546054780146353e+307}. 150 * <pre> 151 TutorialExamples/Tutorial9Cxx/fibonacciRoundingFloat_float64bitCxx_provides_Fibonacci fibonacciGeneralAxiom 71 152 TutorialExamples/Tutorial9Cxx/fibonacciRoundingFloat_float64bitCxx_provides_Fibonacci integer_maximum 153 TutorialExamples/Tutorial9Cxx/fibonacciRoundingFloat_float64bitCxx_provides_Fibonacci fib 71 154 TutorialExamples/Tutorial9Cxx/fibonacciRoundingFloat_float64bitCxx_provides_Fibonacci fib 93 155 TutorialExamples/Tutorial9Cxx/fibonacciRoundingFloat_float64bitCxx_provides_Fibonacci fib 1474 156 * </pre> 157 */ 158 satisfaction fibonacciRoundingFloat_float64bitCxx_provides_Fibonacci = 158 159 float64bitCxx 159 160 with fibonacciRoundingFloat … … 248 249 /** 249 250 * Providing a test setup using 64 bit floats and 64 bit natural numbers for {@link fibonacciRoundingSimple}. 250 * We see the same inaccuracies as for {@link fibonacciRoundingFloat 64_provides_FibonacciCxx},251 * We see the same inaccuracies as for {@link fibonacciRoundingFloat_float64bitCxx_provides_Fibonacci}, 251 252 * i.e., {@code fib(71)} also has an error in the last digit. 252 253 * However, the conversion to integers means we cannot approximate large values of fib. … … 254 255 * which deviates from the correct result 12200160415121876738 in the last 6 digits. 255 256 * Note that in this approximation {@code fib(93)==fib(92)+fib(91)}, even though the answer is wrong, 256 * it just happens to be the case that the computation errors coinside with the assertion.257 * it just happens to be the case that the computation errors of those 3 fibonacci numbers coinside with the assertion. 257 258 * Any higher Fibonacci number flattens out at 18446744073709551615, the highest natural number represented by 64 bits. 258 259 * This is a property of {@link conversionRealIntegerApproximateCxx}. … … 260 261 * 261 262 * <pre> 262 TutorialExamples/Tutorial9Cxx/fibonacciRounding 64_provides_FibonacciCxxfibonacciGeneralAxiom 71263 TutorialExamples/Tutorial9Cxx/fibonacciRounding 64_provides_FibonacciCxxinteger_maximumf264 TutorialExamples/Tutorial9Cxx/fibonacciRounding 64_provides_FibonacciCxxmaximumi265 TutorialExamples/Tutorial9Cxx/fibonacciRounding 64_provides_FibonacciCxxfib 71266 TutorialExamples/Tutorial9Cxx/fibonacciRounding 64_provides_FibonacciCxxfib 93267 TutorialExamples/Tutorial9Cxx/fibonacciRounding 64_provides_FibonacciCxxfibonacciGeneralAxiom 93268 TutorialExamples/Tutorial9Cxx/fibonacciRounding 64_provides_FibonacciCxxfib 94269 * </pre> 270 */ 271 satisfaction fibonacciRounding 64_provides_FibonacciCxx= {263 TutorialExamples/Tutorial9Cxx/fibonacciRounding_float64bitCxx_boundedNatural64bitCxx_provides_Fibonacci fibonacciGeneralAxiom 71 264 TutorialExamples/Tutorial9Cxx/fibonacciRounding_float64bitCxx_boundedNatural64bitCxx_provides_Fibonacci integer_maximumf 265 TutorialExamples/Tutorial9Cxx/fibonacciRounding_float64bitCxx_boundedNatural64bitCxx_provides_Fibonacci maximumi 266 TutorialExamples/Tutorial9Cxx/fibonacciRounding_float64bitCxx_boundedNatural64bitCxx_provides_Fibonacci fib 71 267 TutorialExamples/Tutorial9Cxx/fibonacciRounding_float64bitCxx_boundedNatural64bitCxx_provides_Fibonacci fib 93 268 TutorialExamples/Tutorial9Cxx/fibonacciRounding_float64bitCxx_boundedNatural64bitCxx_provides_Fibonacci fibonacciGeneralAxiom 93 269 TutorialExamples/Tutorial9Cxx/fibonacciRounding_float64bitCxx_boundedNatural64bitCxx_provides_Fibonacci fib 94 270 * </pre> 271 */ 272 satisfaction fibonacciRounding_float64bitCxx_boundedNatural64bitCxx_provides_Fibonacci = { 272 273 use float64bitCxx[ float_to_suffix_f ]; 273 274 use conversionRealIntegerApproximateCxx; 274 275 use boundedNatural64bitCxx[ integer_to_suffix_i ]; 275 } with fibonacciRounding Simple276 } with fibonacciRounding 276 277 approximates Fibonacci[ integer_to_suffix_i ]; 277 278 278 279 /** 279 * Providing a test setup using 80 bit floats and 6 4 bit natural numbers for {@link fibonacciRoundingSimple}.280 * The inaccuracies are similar to {@link fibonacciRounding 64_provides_FibonacciCxx},280 * Providing a test setup using 80 bit floats and 65 bit integers for {@link fibonacciRoundingSimple}. 281 * The inaccuracies are similar to {@link fibonacciRounding_float64bitCxx_boundedNatural64bitCxx_provides_Fibonacci}, 281 282 * but have been postponed to {@code fib(79)==14472334024676222} which has an error in the last digit. 282 283 * The largest Fibonacci number we can approximate reasonably well still is {@code fib(93)==12200160415121876992}, 283 284 * which now deviates from the correct result 12200160415121876738 only in the last 3 digits. 284 285 * <pre> 285 TutorialExamples/Tutorial9Cxx/fibonacciRounding80_provides_FibonacciCxx fibonacciGeneralAxiom 79 286 TutorialExamples/Tutorial9Cxx/fibonacciRounding80_provides_FibonacciCxx integer_maximumf 287 TutorialExamples/Tutorial9Cxx/fibonacciRounding80_provides_FibonacciCxx maximumi 288 TutorialExamples/Tutorial9Cxx/fibonacciRounding80_provides_FibonacciCxx fib 79 289 TutorialExamples/Tutorial9Cxx/fibonacciRounding80_provides_FibonacciCxx fib 93 290 TutorialExamples/Tutorial9Cxx/fibonacciRounding80_provides_FibonacciCxx fib 94 291 * </pre> 292 */ 293 satisfaction fibonacciRounding80_provides_FibonacciCxx = { 286 TutorialExamples/Tutorial9Cxx/fibonacciRoundingSimple_float80bitCxx_boundedInteger65bitCxx_provides_Fibonacci fibonacciGeneralAxiom 79 287 TutorialExamples/Tutorial9Cxx/fibonacciRoundingSimple_float80bitCxx_boundedInteger65bitCxx_provides_Fibonacci integer_maximumf 288 TutorialExamples/Tutorial9Cxx/fibonacciRoundingSimple_float80bitCxx_boundedInteger65bitCxx_provides_Fibonacci maximumi 289 TutorialExamples/Tutorial9Cxx/fibonacciRoundingSimple_float80bitCxx_boundedInteger65bitCxx_provides_Fibonacci fib 79 290 TutorialExamples/Tutorial9Cxx/fibonacciRoundingSimple_float80bitCxx_boundedInteger65bitCxx_provides_Fibonacci fib 93 291 TutorialExamples/Tutorial9Cxx/fibonacciRoundingSimple_float80bitCxx_boundedInteger65bitCxx_provides_Fibonacci fib 94 292 TutorialExamples/Tutorial9Cxx/fibonacciRoundingSimple_float80bitCxx_boundedInteger65bitCxx_provides_Fibonacci fib 1474 293 * </pre> 294 */ 295 satisfaction fibonacciRoundingSimple_float80bitCxx_boundedInteger65bitCxx_provides_Fibonacci = { 294 296 use float80bitCxx[ float_to_suffix_f ]; 295 297 use conversionRealIntegerApproximateCxx; … … 313 315 do echo $file 314 316 $file fibonacciBaseAxiom 315 for i in {0 ,1,2,3,4,5,6,7,8,9}{0,1,2,3,4,5,6,7,8,9}317 for i in {0..99} 316 318 do $file fibonacciGeneralAxiom $i || echo $i 317 319 done … … 351 353 */ 352 354 procedure body( upd d:Pair, obs c:Integer ) { 353 var f = d.f1 + d.f2; 354 d.f2 = d.f1; 355 var p = d; 356 var f = p.f1 + p.f2; 357 d.f2 = p.f1; 355 358 d.f1 = f; 356 359 } … … 407 410 do echo $file 408 411 $file fibonacciBaseAxiom 409 for i in {0 ,1,2,3,4,5,6,7,8,9}{0,1,2,3,4,5,6,7,8,9}412 for i in {0..99} 410 413 do $file fibonacciGeneralAxiom $i || echo $i 411 414 done … … 415 418 */ 416 419 417 /** The Fibonacci function implemented by creating a lookup table with 93 entries and then using this.418 * Computing Fibonacci for 9 3 requires at least64 bit natural numbers.420 /** The Fibonacci function implemented by creating a lookup table with entries including fib(93). 421 * Computing Fibonacci for 94 requires more than 64 bit natural numbers. 419 422 * 420 423 * The implementation first fills an array Fibtable with the Fibonacci numbers starting the base cases 0 and 1, … … 444 447 } 445 448 446 /** Function that creates a {@link Fibtable} for the given number of entries. */449 /** Function that creates a {@link Fibtable} for Fibonacci numbers 0..n. */ 447 450 function initialiseFibtable( n:Intex ) : Fibtable = 448 /** Compute the table of Fibonacci numbers for entries i+1 for i=1,..,n -1. */451 /** Compute the table of Fibonacci numbers for entries i+1 for i=1,..,n. */ 449 452 repeat( 450 453 /** Change the first element of the array to 1, ensuring the base case is corrrectly stored in the Fibonacci array. */ 451 454 change( 452 /** Initialise an array o gn+1 elements, all being 0. */455 /** Initialise an array of n+1 elements, all being 0. */ 453 456 createArray(n+I(),zerointex()), 454 457 I(), … … 463 466 ); 464 467 465 /** A constant {@link Fibtable} with 93 entries - as much as possible for {@code long int}. */468 /** A constant {@link Fibtable} with entries for fib(0)..fib(93) - all possible fibonacci entries for 64 bit natural numbers. */ 466 469 function fibtable () : Fibtable = initialiseFibtable(L() + XL() + III()); 467 470 … … 471 474 472 475 /** 473 * Providing a test setup using 64 bit integers ({@code size_t}) since this allows Fibonacci numbers up to 93. 476 * Providing a test setup using 64 bit natural numbers ({@code size_t} in C++ for 64bit architectures) 477 * which allows Fibonacci numbers up to 93. 474 478 * For argument 94 the lookup function obviously fails. 475 479 */ … … 492 496 for file in TutorialExamples/Tutorial9Cxx/fibonacciExternalCxx 493 497 do echo $file 494 for i in {0 ,1,2,3,4,5,6,7,8,9}{0,1,2,3,4,5,6,7,8,9}498 for i in {0..99} 495 499 do echo -n $i ' ' ; $file fib -i1 fibtable.Fibtable $i 496 500 done
Note:
See TracChangeset
for help on using the changeset viewer.