Stefan_G - Journal of Universal Computer Science, vol. 2,...

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: Journal of Universal Computer Science, vol. 2, no. 5 (1996), 410-426 submitted: 13/5/96, accepted: 13/5/96, appeared: 28/5/96 © Springer Pub. Co. CHAITIN'S TOYLISP ON A CONNEX MEMORY MACHINE 1 Politechnical University of Bucharest, Department of Electronics, Bd. Armata Poporului 1-3, Bucharest 6, Romania, email: stefan@hera.pub.ro. University of Bucharest, Faculty of Mathematics, Str. Academiei 14, Bucharest 1, Romania, email: system@bsu.ro. Gheorghe Stefan  Mihaela Malita  Abstract: This paper describes an implementation of Chaitin's ToyLisp Chaitin '87 on a Connex Memory Machine CMM Stefan '85 . The Connex Memory Machine has  a smaller complexity than previous Universal Machines used to run Lisp programs, so the time and space used in running Lisp programs can be considerably decreased. A ToyLisp like language can be used with a CMM to construct a Lisp CoProcessor for accelerating Lisp processing in conventional architectures. 1 Introduction Improving the performance of a string processing system could be done in two main ways: by de ning and designing a high performance processing unit, having a well tted" set of functions, or by nding a good" memory support for the data structures. We have investigated the second alternative by de ning a more natural" memory support for lists, i.e. a better representation for storing and manipulating lists. We suggest a smart memory",in which some of its functions are performed at the storage level. Two main consequences derive from this approach: the processor attached to the memory becomes simpler and faster, the computational processes are simpler and their time and space complexities decrease. In the '80s a small team in the Polytechnical University of Bucharest designed and implemented a Lisp Machine as a microprogrammed machine. From this experience a new memory model has emerged: the Connex Memory Stefan '85 .2  Our paper has two aims: 1 C. Calude ed.. The Finite, the Unbounded and the In nite, Proceedings of the Summer School Chaitin Complexity and Applications", Mangalia, Romania, 27 June 6 July, 1995. 2 Some applications of this memory were presented in Stefan '91 , Stefan 95 , Hascsi   '95 . Stefan G., Malita M.: Chaitin’ s ToyLisp on a Connex Machine 411 a theoretical one: to o er another model for Universal Machine used to interpret Chaitin's ToyLisp;3 a practical one: to de ne and implement a Lisp CoProcessor starting from a ToyLisp like language as an assembly language. 2 Basic Requirements for String Processing A Lisp-like language e cient implementation requires some unusual features, as: a natural" representation of S-expressions on the physical support, a natural" manipulation of S-expressions, time operation uncorrelated with the string length. All these requirements can be satis ed with a physical support that: nds accesses the starting place of a substring in a string, inserts deletes a symbol in an accessed point, delimits a self-delimited substring. Dealing with symbols implies operations as nding, matching, inserting, deleting, moving, copying. These operations, usually, don't a ect the symbol itself, but its position in the string. Memory functions are crucial in this case. Numerical operations are realized by functions that modify the value of their arguments using processing units. A processor like approach is more tted for numbers. Processor Channel 6 - Memory Fig. 1. The von Neumann Model Having in mind the well known von Neumann model Processor - Channel - Memory, see Fig. 1 we believe that for a more e cient symbol manipulation we need new memory functions instead of more powerful processors. Therefore, our proposal is a new concept of memory: the Connex Memory. 3 The Connex Memory 3.1 Informal De nition of the Connex Memory The connex memory CM is a physical support for a symbolic string in which we can nd any substring, identifying, in such a manner, any place in the string, for reading, inserting or deleting a symbol or a substring of symbols. The content of the CM is a string of variables: v1 v2 : : : vi : : : vn . Each variable vi has: 3 This could be a step towards obtaining a shorter diophantine equation describing Chaitin's Omega Number, Chaitin '87, Calude '94 . 412 Stefan G., Malita M.: Chaitin’ s ToyLisp on a Connex Machine a value from a nite alphabet A, a state which is marked or non-marked; the access point is at the rst marked variable. ^ For example, the content in some place in CM is the string: ...bubu ^ood g boy... In Fig. 2 we can see the structure of the representation of the variables from the string: one bit for the marker and m = log2cardA bits for each symbol in the alphabet A. On any string stored in CM we can apply the set of functions described in the following de nition. De nition 1. The connex memory CM1 is a physical support for a string of variables, having values from a nite set of symbols A and two states: nonmarked or marked, over which we can apply the following set of functions: RESET s : all the variables after the rst marked variable take the value s F IND s : all the variables that follow a variable having the value s switch to the marked state and the rest switch in the non-marked state C onditionedFIND s : all the variables that follow a variable having the value s and being in the marked state switch in the marked state and the rest switch in the non-marked state I NSERT s : the value s is inserted before the rst marked variable READ upjdownj : the output has the value of the rst marked variable and the marker moves one position to right up or to left down or remains unchanged   DELETE : the value stored in the rst marked position is deleted, the position remains marked  the output has the value of the rst marked variable and the symbols from the right are moved one position left access point    marked variables  0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 ub  b u  g o o d +   boy Fig. 2. The content of CM. An example For di erent purposes in di erent stages of the computational process we need di erent types of markers. Until now our example has involved only one marker. We shall consider an extended de nition of CM with two or more markers. In this way we could colour" the symbols of the string with more than one colour" marker. De nition 2. The CM2 has in addition to the set of functions de ned in for CM1 see De nition 1 the following new function: Stefan G., Malita M.: Chaitin’ s ToyLisp on a Connex Machine 413 S ET POINTER p1jp2j:::jpk: the pointer pi i = 1; 2; :::; k is set to the rst position of the marker and modi es the next functions as follows the square brackets are used to indicate optional elds in the mnemonics of the function: I NSERT pi ; s: inserts the symbol s in the position indicated by the pointer pi; if a pointer is not indicated, s is inserted to the rst occurrence of the marker; READ upjdownj , pi : starts reading from the position indicated by the pi pointer which is a ected in the same manner as the marker; DELETE pi : deletes the position pointed by pi. According to these de nitions the CM is structured as a bi-directional shift register in which any signi cant point is marked, as a consequence of an associative sequential mechanism used to nd a name in a number of steps equal to the length of the name. In the marked place, read, insert and delete can be performed. Theoretically, the CM at the right end is unlimited, and, consequently, can be used for simulating or emulating e ciently any number of registers having an unspeci ed length theoretical in nite. Brie y: CM = is a CAM designed as a Bi-directional Shift Register left delimited by the rst marker. Functions Data - - CONNEX MEMORY Fig. 3. Block Diagram of CM The block diagram of CM1 from Fig. 3 shows the connections for data and functions de ned before. We should not be surprised that this kind of memory has no addresses. Indeed, we don't need them because the access point is found by an associative search. In this way we avoid the logn connections used for addressing a standard memory. It is a real joy to discover that this type of memory could remain, with an appropriate design, in the class of On. At this reduced complexity, all functions are executed in time T n 2 O1, in one clock cycle. For example, using the 16 Mb DRAM technology we realize our CM of 64 Ksymbol, where each symbol is encoded in 12 bits with 4 markers having 16 states per symbol. 3.2 The Connex Memory at Work Let us see some examples illustrating the main abilities of the CM. Example 1. Using the CM1 we can nd any substring in a string. Suppose that we have in a CM the following string: :::bubu bad butcher:::bulgaria:::::: and we want to select and read the list of bubu's properties, i.e., bad butcher. The following sequence of functions is executed: 414 Stefan G., Malita M.: Chaitin’ s ToyLisp on a Connex Machine FIND  CFIND b CFIND u CFIND b CFIND u CFIND blank loop READ up until  repeat The content of the CM becomes successively the marked places are indicated by oversigned symbols: ^ ^ ^ ...bubu bad butcher...bulgaria ...... ...b^bu b^d butcher...b^lgaria ...... u a u ^u bad butcher...bu^garia ...... ...bub l ...bub^ bad butcher...bulgaria ...... u ...bubu^bad butcher...bulgaria ...... ...bubu ^ butcher...bulgaria ...... bad ^ ...bubu bad butcher...bulgaria ...... out =  ...bubu b^d butcher...bulgaria ...... out = b a ^ ...bubu bad butcher...bulgaria ...... out = a ...bubu bad^butcher...bulgaria ...... out = d and so on, until: ...bubu bad butcher^ ...bulgaria ...... out = . Example 2. Let us suppose that we want to change the rst property of bubu with the value good. The sequence of functions will be: FIND  CFIND b CFIND u CFIND b CFIND u CFIND blank READ up loop DELETE until blank repeat INSERT g INSERT o INSERT o INSERT d INSERT blank Now the new content of the CM becomes: ...bubu good butcher...bulgaria ...... Stefan G., Malita M.: Chaitin’ s ToyLisp on a Connex Machine 415 4 CM Machine as a Universal Machine The Connex Memory Machine CMM has the computational power of a Universal Turing Machine. In order to compare the CMM with other models we will make a short review of two other models: Universal Turing Machine UTM and Chaitin's Register Machine RM. 4.1 Universal Turing Machine Instead of the classical de nition for a Turing Machine TM with: an in nite tape containing a string of symbols that can be read or modi ed, a nite automaton which, for UTM, knows" how to interpret a symbolic substring on the tape as a TM description, a read write head which accesses the tape, we propose a TM version more appropriate to the actual technology. In Fig. 4 the UTM contains: an in nite Random Access Memory RAM, instead of the tape a nite automaton, as interpreter for TM description from the RAM an up-down counter that generates the address to the RAM. Q - Finite Automaton 6 C commands - U D Counter ? Addresses A data - RAM Fig. 4 Universal Turing Machine UTM De nition 3 An UTM is a 4-tuple Fig. 4: where: A, the nite alphabet for the RAM, Q, the nite set of states of the automaton, f , the transition function of UTM, f : A  Q ! A  Q  C , where C = fUP; DOWN; ,g is the set of commands given by the automaton to the U D Counter,  2 A is a special symbol delimiting the active space in RAM. Therefore, a TM is a three part system: the nite automaton for control, the in nite automaton for addressing the RAM, and the in nite RAM. UTM = A; Q; f ;  416 Stefan G., Malita M.: Chaitin’ s ToyLisp on a Connex Machine 4.2 Chaitin's Register Machine G. J. Chaitin  Chaitin '87, '94  de nes the RM optimizing the UTM4 The goal of this approach is to built a Lisp oriented machine with a better solution for list inserting and deleting. Q - Finite Automaton A u - R1 6 F S u u - R2 6 u . . . Rm 6 Fig. 5. Registers Machine RM In Fig. 5 the RM has a nite automaton as interpreter for ToyLisp programs and a nite number of in nite left right shift registers used as stacks initially, in one register we have a Lisp object to be evaluated and the nal result will be found in any register. De nition 4. A RM see Fig. 5 is a 5-tuple: RM = A; Q; F; R; g where: A, the nite alphabet for registers, Q, the nite set of states of the automaton, F, the nite set of functions applied to the content of the registers, F = fREAD; WRITE; PUSH; POP g, R, the nite set of registers, g, the transition function of RM, g : Q  R  A ! Q  R  A  F . It is obvious that a RM with minimum two registers is universal. 4 to construct his paradoxal Big Omega. Stefan G., Malita M.: Chaitin’ s ToyLisp on a Connex Machine 417 4.3 Connex Memory Machine A new universal model of computation oriented towards list tree processing. satis ng all requirements announced in the second section of this paper fast access in any point, easy in sert delete in the accessed point, e cient delimiting of a substring is brie y described for more technical details see Stefan '85, '86,  '94 . CMM Fig. 6 has two main parts: a nite automaton an in nite CM that stores strings of symbols Q - Finite Automaton G functions - CM A data Fig. 6 Connex Memory Machine CMM The di erences between CMM and the previous UM models are: CMM has only one register which stores any number of strings without access penalties; instead of a serial string access, CMM allows a random" access using associative mechanisms, so the access time is in O1. De nition 5. A CMM see Fig. 6 is a 4-tuple: CMM = A; Q; G; h where: A; the nite alphabet for the CM, Q; the nite set of states of the automaton, G; is the nite set of CM's functions see De nition 1 and De nition 2, h; is the transition function of CMM, h : Q  A ! Q  A  G. 4.4 Time Performances The main di erences between these three models is the execution time for the basic operations see Section 2 in string processing: the time for nding accessing a point in a string, TF n, the time for insert delete operations, TI=D n, the time for delimiting substrings of m length, TLm. For the three previous models we have: UTM: TF n 2 On, TI=D n 2 On, TLm 2 Om 418 Stefan G., Malita M.: Chaitin’ s ToyLisp on a Connex Machine RM:TF n 2 On, TI=D n 2 O1, TLm 2 Om CMM: TF n 2 O1 in one cycle, TI=D n 2 O1 in one cycle, TLm 2 O1 In all situations the CMM model has a better performance; even more, for TF n and TI=D n the execution time is in one cycle Stefan '86, '94 .  5 The ToyLisp Interpreter We start from the Pure Lisp Model proposed by G. J. Chaitin Chaitin '87 , in which: atoms are monosymbolic; there are ten primitive functions: ATOM, EQUAL, CAR, CDR, CONS, OUTPUT, QUOTE, IF-THEN-ELSE, EVAL, SAFE-EVAL; LAMBDA expressions have the form &vb where v is the list of variables and b is the body; for de ning variables we use &xe where x is the variable and e is an Sexpression with value v; xv is concatenated with the old environment; for de ning functions we use &fxyz d where fxyz is one or more atoms and d is an S-expression; f &xyz d is concatenated with the old environment; if an S-expression is not of the form & : : : then it is evaluated in the current environment. 5.1 The Pure Lisp Coprocessor In order to evaluate ToyLisp programs we conceived a CMM as a Pure Lisp Coprocessor PLC. The structure of PLC is shown in Fig. 7, where: I ; is the interface on the host computer bus, C A; is the control automaton being able to execute subroutines, R; is a register which can store an atom, U DC; is an up-down counter used as system symbol generator, CM, is the connex memory. Stefan G., Malita M.: Chaitin’ s ToyLisp on a Connex Machine 419 Host BUS ? Sync. - Commands CA 6 t ? I t ? Data UDC CM - R - Fig. 7. Pure Lisp Coprocessor The PLC executes an unending cycle printevalread.The content of the CM is organized as follows: @environment $S , expression temporary environment and is: @environment $ after PRINT @environment $S , expression to be evaluated  after READ @environment $evaluated S , expression temporary environment after EVAL The content of CM is equivalent with the content of three unbounded" registers that store the environment, the evaluated S-expression and the temporary environment. 5.2 The Interpreter We are using a string reduction mechanism, as it o ers a smaller complexity of description of the evaluation process. We shall exemplify by describing the CAR function. For more details about the entire interpreter see M^u '96 . t ; CAR ; the marker is on + the CAR sign ; the substring :::xf+!"s = expr" becomes :::x!"CARs = expr" ; x is marked or the rst symbol of the non-evaluated argument is marked ; setq cm 'z f + ! f f a b g c g g d  2  ; &car ! z ! f a b g d  0  defun &car  readup condeqread  '!readup condeqread  ' &deleteendsex insert ' readdownclrsexreadupbacksex f f 420 Stefan G., Malita M.: Chaitin’ s ToyLisp on a Connex Machine   clrbr&deletereaddown ; ENDSEX  ; the rst symbol of an S-expression is marked and ; the marker will be moved at the beginning of the next symbol ; the pointer is on the rst position of m ; if the marker is on a parentheses it is moved after the next paranthesis ; if the marker is an atom it is moved on the next atom ; uses special symbols $ and  ; setq cm ' f 1 2 f 4 f 6 7 g 9 g g  0 ; endsex !  f 1 2 f 4 f 6 7 g9 g g 11 defun endsex  condneqread  ' readup tinsert '$insert ' readup whileneqtopstack ' condeqread  ' push eqread  ' pop readup delstack  f g g f g ; CLRSEX  ; deletes the S-expression with the marked beginning ; returns cm modi ed defun clrsex  ifeq ' read  progn insert '*endsexinsert '*find '*readdown&delete whileeqread  '*&delete &delete &delete  f ; BACKSEX  ; the rst marker is on a right par g ; changes the marker to the corresponding f ; setq cm ' f a b s d c g f 7   ; backsex ! f a b s d c g f 0 defun backsex  readdown ifeqread  '  progn readupinsert '$insert ' readdownreaddownreaddown whileneqtopstack '  readdown g g g Stefan G., Malita M.: Chaitin’ s ToyLisp on a Connex Machine 421  delstack  condeqread  ' push eqread  ' pop g f ; CLRBR ; delete pointed bracket and its corresponding bracket, returns cm modi ed ; special symbol * defun clrbr  insert '*endsexreaddown&deletefind '*readdown&delete &delete ; TOPSTACK  defun topstack ;returns the top of the stack, modifies let v insert 'find '$setq vread find 'readdown&delete v cm ; PUSH  ; pushes the symbol g in the stack after $ defun push  insert 'find '$insert ' find 'readdown&delete g ; POP  defun pop  ;pops the symbol from the top of the stack insert 'find '$&deletefind 'readdown &delete ; DELSTACK  defun delstack  ;deletes the stack insert 'find '$readdown&deletefind 'readdown &delete 5.3 Conclusions The current approach in Lisp implementation has imposed CAR and CDR as basic functions. Our di erent way of representing and processing the list in CM, as a connex string, may emphasize other basic functions such as: APPEND, MEMBER, LISTATOMS, INTERSECTION, UNION, DELETE, MATCH. Future work will be focused on optimizing the execution time and the size of memory, using graph reduction mechanisms. One of the next steps is to test Lisp benchmarks on the simulated PLC in order to compare our approach with other models or frequently used computer architectures. 422 Stefan G., Malita M.: Chaitin’ s ToyLisp on a Connex Machine References Calude '94 Calude, C. : Information and Randomness, Springer-Verlag, Brlin, 1994. Chaitin '87 Chaitin, G. J. : Algorithmic Information Theory, Cambridge Univ. Press, 1987. Chaitin '94 Chaitin, G. J. : The Limits of Mathematics IV, IBM Research Report RC 19671, e-print chaodyn 9407009, July 1994. Hascsi '95 Hascsi, Z., Stefan, G. : The Connex Content Addressable Memory  C2AM", in Proceedings of 21st European Solid State Circuits, Lille, France, Sept. 1995, 422-425. M^u '96 M^u, B., Corina M^u : ToyLisp Interpreter on a Connex Memory Machine, t t t in C. Calude ed.. The Finite, the Unbounded and the In nite, Proceedings of the Summer School Chaitin Complexity and Applications", Mangalia, Romania, 27 June 6 July, 1995. Stefan '85 Stefan, G., Bistriceanu, V., Pun, A. : Towards a Natural Mode of Lisp   a Implementation", in Systems for Arti cial Intelligence, Romanian Academy Publishing House, Bucharest, 1991, 218-224. in Romanian Stefan '86 Stefan : Connex Memory" in Proceedings of National Conference on Elec  tronics, Telecommunications, Automatics and Computers, Bucharest, 1986 Vol. 2, IPB, Bucureti, 1986, 79 - 81. in Romanian s Stefan '91 Stefan, G., Drghici, F. : Memory Management Unit - a New Principle for   a LRU Implementation" in Proceedings of 6th Mediterranean Electrotechnical Conference, Ljubljana, Yugoslavia, May 1991, 281-284. Stefan '94 Stefan, G.: The Connex Memory. A Physical Support for Tree List   Processing", Technical Report, Center for New Electronic Architecture of the Romanian Academy, February 1994. Stefan '94a Stefan, G., Hascsi, Z.: The Internal Structure of the Connex Memory",   Technical Report, Center for New Electronic Architecture of the Romanian Academy, April 1994. Stefan '95 Stefan, Mihaela Malita : The Eco-Chip: A Physical Support for Arti cial    Life Systems", in Arti cial Life. Grammatical Models, ed. by Gh. Pun, Black a Sea University Press, Bucharest, 1995, 260-275. Stefan G., Malita M.: Chaitin’ s ToyLisp on a Connex Machine 423 A The Connex Memory. First Version: CM1 ; The First Version of the Connex Memory ; Its Functions are Described in LISP ; Representation: the content of memory is a list cm = s m ; Where: s is a list containing the symbols on which we work ; m is the list of numbers representing the marked position in s ; Ex: cm = a b c a d1 4 means b and d are marked ; the rest are non-marked ; setq cm '$ nil  ; cm is a global variable ; RST p ; all the symbols in s from cm = s m are substituted with symbol p ; all markers are deleted, m = , returns cm ; SETQ CM QUOTE A B C D E 2 4 ; RST QUOTE P ! P P P P P NIL defun RST p ; cm = sm returns cm labelsmakep k ifnull knilcons pmake pcdr k  setq cmlistmake pcar cm ' defun read  first-marked  ; READ  ; returns the rst marked symbol and cm is unchanged ; SETQ CM QUOTE A B C D 2 ; READ  ! C ; CM ! A B C D 2 defun first-marked  ; =   returns let n caadr cm s car cm if null n nil nth n s  cm sm rst pointed symbol ; nthnL returns the n-th element from L seen as a vector ; READUP  ; returns the rst marked symbol and modi es cm ; moving the marker one position right ; SETQ CM QUOTE A B C D 1 ; READUP ! B ; CM ! A B C D 2 defun readup  ; cm = s m returns rez and modifies cm let*scar cmmcadr cmncar mkcadr m rezfirst-marked cond null nrez 424 Stefan G., Malita M.: Chaitin’ s ToyLisp on a Connex Machine  and k= k1+nsetq cmlist scdr m rez  =1+nlength ssetq cmlist s nilrez tsetq cmlist scons1+ncdr mrez ; READDOWN  ; returns the rst marked symbol and modi es cm with ; the rst marker moved one position left ; SETQ CM QUOTE A B C 1 2 ; READDOWN ! B ; CM ! A B C 0 2 defun readdown  ; cm = s m returns rez ; and modifies the first marker let*scar cmmcadr cmncar mkcadr m rezfirst-marked cond null nrez =n 0setq cmlist scdr mrez and k=n1+length ssetq cmlist scdr mrez tsetq cmlist scons1-ncdr mrez  ; DELETE  ; returns the rst marked symbol and deletes it from cm ; SETQ CM QUOTE A B C D E F 1 4 ; &DELETE ! B ; CM ! A C D E F 1 3 defun &delete  ;cm = s m returns first marked symbol ; and modifies let*scar cmmcadr cm restcdr mncar mkcadr mrezfirst-marked cond null ssetq cmlist nil nilrez null nrez = n1+length ssetq cmlisttake n s1-nrez null restsetq cmlisttake n smrez = n1-ksetq cmlisttake n smapcar '1- restrez tsetq cmlisttake n scons nmapcar '1-restrez  defun taken s ; takes the -th element from a list cond null snil = n 0cdr s tconscar stake1- ncdr s  cm n s ; INSERT p Stefan G., Malita M.: Chaitin’ s ToyLisp on a Connex Machine 425 ; inserts p in front of the rst marked symbol ; if there is no marked symbol everything remains unchanged ; the markers shift one position right returns cm modi ed ; SETQ CM QUOTE A B C D 2 ; INSERT QUOTE P ! A B P C D 3 defun insertp ;cm = s m, p symbol inserted in cm modifies cm ; returns let*scar cmmcadr cmncar m cond null ssetq cmlist nil nil null msetq cmlist s nil = nlength ssetq cmlistappend slist p1+n t setq cmlistput p n smapcar '1+m  defun put k n l ; puts in the -th position in list cond null lnil = n 0cons k l tconscar lput k1- ncdr l  cm k n l ; FIND p ; all the markers after p are marked ; the other markers are deleted, returns cm modi ed ; SETQ CM QUOTE A P C D P F 2 4 ; FIND QUOTE P ! A P C D P F 2 5 defun find p ; cm = s m letscar cm labelspositionp s r n condnull sreverse r equal pcar sposition pcdr scons n r1+ n tposition pcdr sr1+n  setq cmlist sposition p s nil 1  ; CFIND p ; conditioned nd of p in the list s from cm = s m ; all the markers after p that are marked are shifted one position right ; all the other markers are removed, returns cm modi ed ; SETQ CM QUOTE A B P C D P A P F 2 7 ; CFIND QUOTE P ! A B P C D P A P F 3 8 defun cfind p ; cm = s m modifies and returns cm letscar cmmcadr cm labelsmarkp s m r ;r result marker list condornull snull mreverse r 426 Stefan G., Malita M.: Chaitin’ s ToyLisp on a Connex Machine  setq cmlist smark p s m nil  equal pnthcar msmark p scdr m cons1+car mr tmark p scdr mr ...
View Full Document

Ask a homework question - tutors are online