Inital commit

This commit is contained in:
Jens Axel Søgaard 2012-06-20 17:20:30 +02:00
parent 5995bbdd36
commit 1ae55396e4
30194 changed files with 140566 additions and 1 deletions

View File

@ -1,4 +1,21 @@
Bracket
=======
A computer algebra system (CAS) for high school students
This source repository holds the beginning of a CAS (computer algebra
system) written in the programming language Racket.
The goal is not to write a CAS with the scope of Maxima and Mathematica,
but rather to make CAS that can handle high school problems including
symbolic equation solving, differentiation, integration and sums.
The GUI will be inspired by NSpire which interface is very accessible
to high school students (but whose programming language, well, is
rather poor). Since Racket supports platforms independent GUIs til
program will be available on Windows, OS X, and, Linux.
That said, Bracket is not in a usable shape yet. Development has
just begon.
Spin off mathematics libraries will be made available on PLaneT.
/soegaard

10
bracket/bracket-info.rkt Normal file
View File

@ -0,0 +1,10 @@
#lang racket
(provide get-language-info)
(define (get-language-info data)
(lambda (key default)
(case key
[(configure-runtime)
'(#(bracket/runtime-config configure #f))]
[else default])))

20
bracket/bracket-lang.rkt Normal file
View File

@ -0,0 +1,20 @@
#lang racket
(require "lang/parser.rkt")
(error-print-source-location #t)
(require (submod "bracket.rkt" symbolic-application)
;(submod "bracket.rkt" bracket)
)
(provide (all-from-out racket))
(provide (all-defined-out)
(for-syntax #%module-begin)
#%module-begin)
(define-syntax (DeclareVars stx)
(syntax-case stx ()
[(_ sym ...)
#'(begin (define sym 'sym) ...)]))

1372
bracket/bracket.rkt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
#lang scheme
(provide #%infix)
(require scheme/stxparam)
(define-syntax-parameter #%infix
(λ (stx)
(syntax-case stx ()
[(_ expr) #'expr])))

View File

@ -0,0 +1,354 @@
#lang racket
(require "parameter.rkt")
(require syntax/srcloc)
;;;
;;; NOTES:
;;; Changes from planet version: ]] (CDB) Bug fixed
;;; Strings are supported.
;;; Assignments changed from set! to define.
;;; Assignment of functions.
;;; Bug fix: identifiers with more than one _ wasn't converted correctly
; <e> = <num>
; | <string>
; | <id> variable reference
; | <e> [ <args> ] application
; | { <args> } list construction
; | <e> + <e> addition
; | <e> - <e> subtraction
; | <e> * <e> multiplication
; | <e> / <e> division
; | <e> ^ <e> exponentiation
; | - <e> negation
; | ( <e> ) grouping
; | <id> ( <args> ) := <e> function definition
; <id> An identifier begins with a letter,
; and is optionally followed by series of letters, digits or underscores.
; An underscore is converted to a -. Thus list_ref will refer to list-ref.
; <num> A number is an non-empty series of digits,
; optionally followed by a period followed by a series of digits.
; <string> A number is a " followed by a series of non-" characters followed by a " .
(provide parse-expression)
(require parser-tools/yacc
parser-tools/lex
(prefix-in : parser-tools/lex-sre)
syntax/readerr)
(define-tokens value-tokens (NUMBER STRING IDENTIFIER IDENTIFIEROP IDENTIFIER:=))
(define-empty-tokens
op-tokens
(newline
:=
OP CP ; ( )
CP:= ; ):=
OB CB ; [ ]
OC CC ; { }
ODB ; [[ ]]
COMMA ; ,
SEMI ; ;
PERIOD ; .
LAMBDA ; lambda or λ
SQRT ; √
NEG ; ¬ (logical negation)
LESS-EQUAL ; <= or ≤
GREATER-EQUAL ; >= or ≥
NOT-EQUAL ; <> or ≠
= < >
+ - * / ^
DEFINE
EOF))
(define-lex-abbrevs
[letter (:or (:/ "a" "z") (:/ #\A #\Z) )]
[digit (:/ #\0 #\9)]
[string (:: #\" (:* (:~ #\")) #\")]
[identifier (:: letter (:* (:or letter digit #\_ #\?)))]
[identifier:= (:: letter (:* (:or letter digit #\_ #\?)) ":=")]
[identifierOP (:: letter (:* (:or letter digit #\_ #\?)) "(")])
(define (string-drop-right n s)
(substring s 0 (- (string-length s) n)))
(define expression-lexer
(lexer-src-pos
[(eof) 'EOF]
[(:or #\tab #\space #\newline) ; this skips whitespace
(return-without-pos (expression-lexer input-port))]
[#\newline (token-newline)] ; (token-newline) returns 'newline
[(:or ":=" "+" "-" "*" "/" "^" "<" ">" "=" "\"") (string->symbol lexeme)]
["(" 'OP]
[")" 'CP]
["[" 'OB]
["]" 'CB]
["{" 'OC]
["}" 'CC]
["[[" 'ODB]
; ["]]" 'CDB]
["," 'COMMA]
[";" 'SEMI]
["." 'PERIOD]
[#\λ 'LAMBDA]
["lambda" 'LAMBDA]
["" 'SQRT]
["¬" 'NEG]
["" 'LESS-EQUAL]
["<=" 'LESS-EQUAL]
["" 'GREATER-EQUAL]
[">=" 'GREATER-EQUAL]
["<>" 'NOT-EQUAL]
["" 'NOT-EQUAL]
["define" 'DEFINE]
[string
(token-STRING (substring lexeme 1 (- (string-length lexeme) 1)))]
; The parser can only look ahead 1 token, so we have 3
; different identifiers to see whether := or ( comes after the identfier.
; This is enough to prevent shift/reduce conflicts between atom, definition,
; and application.
[identifier:=
(token-IDENTIFIER:=
(string->symbol (string-drop-right 2 (regexp-replace* #rx"_" lexeme "-"))))]
[identifierOP
(token-IDENTIFIEROP
(string->symbol (string-drop-right 1 (regexp-replace* #rx"_" lexeme "-"))))]
[identifier
(token-IDENTIFIER (string->symbol (regexp-replace* #rx"_" lexeme "-")))]
[(:+ digit) (token-NUMBER (string->number lexeme))]
[(:: (:+ digit) #\. (:* digit)) (token-NUMBER (string->number lexeme))]))
;; A macro to build the syntax object
(define-syntax (b stx)
(syntax-case stx ()
[(_ o value start end)
#'(b o value start end 0 0)]
[(_ o value start end start-adjust end-adjust)
(with-syntax
((start-pos (datum->syntax #'start
(string->symbol
(format "$~a-start-pos"
(syntax->datum #'start)))))
(end-pos (datum->syntax #'end
(string->symbol
(format "$~a-end-pos"
(syntax->datum #'end))))))
#`(datum->syntax
o
value
(list (if (syntax? o) (syntax-source o) 'missing-in-action--sorry)
(if (and o (syntax-line o))
(+ (syntax-line o) (position-line start-pos) start-adjust -1) #f)
(if (and o (syntax-column o))
(+ (syntax-column o) (position-offset start-pos) start-adjust) #f)
(if (and o (syntax-position o))
(+ (syntax-position o) (- (position-offset start-pos) start-adjust 1)) #f)
(- (+ (position-offset end-pos) end-adjust)
(+ (position-offset start-pos) start-adjust)))
o o))]))
; for testing: builds lists instead of syntax objects
#;(define-syntax (b stx)
(syntax-case stx ()
[(_ _ val _ _)
#'val]))
(define (display-position-token pos)
(display (position->list pos)))
(define (position->list pos)
(list (position-offset pos)
(position-line pos)
(position-col pos)))
(define (expression-parser source-name orig-stx)
(define o orig-stx)
(parser
(src-pos)
; (suppress) ; hmm...
;(debug "parser-dump.txt")
;(yacc-output "parser-dump.yacc")
(start start)
(end newline EOF)
(tokens value-tokens op-tokens)
(error (lambda (token-ok? name val start end)
; The first argument will be #f if and only if the error is that an invalid token was received.
; The second and third arguments will be the name and the value of the token at which the error was detected.
; The fourth and fifth arguments, if present, provide the source positions of that token.
#;(unless #f #; (string? (syntax->datum o))
(display "DEBUGXXX: ")
(display (list o token-ok? name val start end))
(display-position-token start) (newline)
(display-position-token end) (newline)
(displayln source-name)
(newline))
(error-print-source-location #t)
(displayln "Syntax error")
(raise-read-error
"Syntax error"
source-name
(position-line start)
(position-col start)
(position-offset start)
(+ (- (position-offset end) (position-offset start))))
#;(raise-syntax-error
#f
"syntax error"
(datum->syntax
#'here 'here
(list
source-name
(position-line start)
(position-col start)
(position-offset start)
(+ (- (position-offset end) (position-offset start))))))))
(precs ; (left :=)
; (right OP)
(left - +)
(left * /)
(right OB)
(right ^)
(left =) ; comparisons
(right NEG)
(left SEMI)
; (right IDENTIFIER)
)
(grammar
(start [(exp) (b o `(#%infix ,$1) 1 1)]
[() #f])
;; If there is an error, ignore everything before the error
;; and try to start over right after the error
(args [(exp) (b o (list $1) 1 1)]
[(exp COMMA args) (b o (cons $1 $3) 1 3)]
[() '()])
(ids [() '()]
[(IDENTIFIER ids) (b o (cons $1 $2) 1 2)])
(parenthensis-exp
[(OP exp CP) $2])
(atom
[(NUMBER) (b o $1 1 1)]
[(IDENTIFIER) (prec IDENTIFIER) (b o $1 1 1)]
[(STRING) (b o $1 1 1)]
[(parenthensis-exp) $1])
(construction-exp
[(OC args CC) (b o `(,(b o 'list 1 3) ,@$2) 1 3)]
[(OP LAMBDA ids PERIOD exp CP) (b o `(,(b o 'lambda 2 2) ,$3 ,$5) 1 6)]
[(atom) $1])
(application-exp
;[(application-exp OB args CB) (b o `(,$1 ,@$3) 1 4)] ; function application
; Due the extra ( in IDENTIFIEROP we need to adjust the end with -1.
[(IDENTIFIEROP args CP) (b o `(,(b o $1 1 1 0 -1) ,@$2) 1 3)] ; function application
[(application-exp OP args CP) (prec OP) (b o `(,$1 ,@$3) 1 4 )] ; function application
[(application-exp ODB exp CB CB) (b o `(,(b o 'list-ref 1 4) ,$1 ,$3) 1 4)] ; list ref
[(construction-exp) $1])
#;(implicit-exp
[(application-exp application-exp) (prec *) (b o `(,(b o '* 1 2) ,$1 ,$2) 1 2)] ; implicit
[(application-exp) $1])
(power-exp
[(application-exp ^ power-exp) (prec ^) (b o `(expt ,$1 ,$3) 1 3)]
[(application-exp) $1])
(sqrt-exp
[(SQRT sqrt-exp) (b o `(,(b o 'sqrt 1 1) ,$2) 1 2)]
[(power-exp) $1])
(negation-exp
[(- negation-exp) (b o `(,(b o '- 1 1) ,$2) 1 2)]
[(sqrt-exp) $1])
(multiplication-exp
[(multiplication-exp * negation-exp) (prec *) (b o `(,(b o '* 2 2) ,$1 ,$3) 1 3)]
[(multiplication-exp / negation-exp) (prec /) (b o `(,(b o '/ 2 2) ,$1 ,$3) 1 3)]
;[(multiplication-exp negation-exp) (prec *) (b o `(,(b o '* 1 2) ,$1 ,$2) 1 2)]
[(negation-exp) $1])
(addition-exp
[(addition-exp - multiplication-exp) (prec -) (b o `(,(b o '- 2 2) ,$1 ,$3) 1 3)]
[(addition-exp + multiplication-exp) (prec +) (b o `(,(b o '+ 2 2) ,$1 ,$3) 1 3)]
[(multiplication-exp) $1])
(order-exp
[(addition-exp LESS-EQUAL addition-exp) (prec =) (b o `(,(b o '<= 2 2) ,$1 ,$3) 1 3)]
[(addition-exp < addition-exp) (prec =) (b o `(,(b o '< 2 2) ,$1 ,$3) 1 3)]
[(addition-exp GREATER-EQUAL addition-exp) (prec =) (b o `(,(b o '>= 2 2) ,$1 ,$3) 1 3)]
[(addition-exp > addition-exp) (prec =) (b o `(,(b o '> 2 2) ,$1 ,$3) 1 3)]
[(addition-exp NOT-EQUAL addition-exp) (prec =) (b o `(not (,(b o '= 2 2) ,$1 ,$3)) 1 3)]
[(addition-exp = addition-exp) (prec =) (b o `(,(b o '= 2 2) ,$1 ,$3) 1 3)]
[(addition-exp) $1])
(logical-negation-exp
[(NEG logical-negation-exp) (prec NEG) (b o `(,(b o 'not 1 1) ,$2) 1 2)]
[(order-exp) $1])
; The no DEFINE version conflicts with application.
; Solution? Move definition with := into rule for application.
(assignment-exp
;[(DEFINE IDENTIFIER := assignment-exp) (b o `(,(b o 'define 3 3) ,$2 ,$4) 2 4)]
;[(DEFINE IDENTIFIER OP args CP := assignment-exp) (b o `(,(b o 'define 4 4) (,$2 ,@$4) ,$7) 2 6)]
[(IDENTIFIER:= assignment-exp) (b o `(,(b o 'define 1 1)
,(b o $1 1 1
; adjust end with -2 due to the chars in :=
0 -2)
,(b o $2 2 2)) 1 2)]
[(IDENTIFIEROP args CP := assignment-exp) (b o `(,(b o 'define 2 2) (,$1 ,@$2) ,$5) 1 5)]
[(logical-negation-exp) $1])
(compound-exp
[(compound-exp SEMI assignment-exp) (b o `(,(b o 'begin 2 2) ,$1 ,$3) 1 3)]
[(assignment-exp) $1])
(exp
[(compound-exp) $1]))))
(define (parse-expression src stx ip)
(port-count-lines! ip)
((expression-parser
src
; If you change any of these values, then
; you must change the builder b which uses
; the the values in here to add to newly read
; objects. If the lexer/parser was only to
; read from entire files, there would be no problem,
; but sometimes one must read from strings
; entered in a repl. There the syntax-objects must be
; adjusted.
(datum->syntax #f
'here
(list src
1 ; line 1
0 ; column 0
1 ; offset/position 1 (contract for datum->syntax requires a positive offset)
#f) ; span
)) ; no properties
; The following Tom Foolery is to needed to turn
; SEMI EOF into EOF
; This allows one to have an optional semi colon in the end of the file.
(let ([peek (expression-lexer ip)]
[peek1 (expression-lexer ip)])
(define (next)
(cond
[(eq? (position-token-token peek) 'EOF) (void)]
[else (set! peek peek1)
(set! peek1 (expression-lexer ip))]))
(λ ()
(if (and (eq? (position-token-token peek) 'SEMI)
(eq? (position-token-token peek1) 'EOF))
(begin0 peek1 (next))
(begin0 peek (next)))))))

1564
bracket/lang/parser-dump.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,78 @@
%token NUMBER
%token STRING
%token IDENTIFIER
%token IDENTIFIEROP
%token IDENTIFIER:=
%left '-' '+'
%left '*' '/'
%right 'OB'
%right '^'
%left '='
%right 'NEG'
%left 'SEMI'
%start (start)
%%
start: exp
|
;
args: exp
| exp 'COMMA' args
|
;
ids:
| IDENTIFIER ids
;
parenthensis-exp: 'OP' exp 'CP'
;
atom: NUMBER
| IDENTIFIER %prec IDENTIFIER
| STRING
| parenthensis-exp
;
construction-exp: 'OC' args 'CC'
| 'OP' 'LAMBDA' ids 'PERIOD' exp 'CP'
| atom
;
application-exp: IDENTIFIEROP args 'CP'
| application-exp 'OP' args 'CP' %prec OP
| application-exp 'ODB' exp 'CB' 'CB'
| construction-exp
;
power-exp: application-exp '^' power-exp %prec ^
| application-exp
;
sqrt-exp: 'SQRT' sqrt-exp
| power-exp
;
negation-exp: '-' negation-exp
| sqrt-exp
;
multiplication-exp: multiplication-exp '*' negation-exp %prec *
| multiplication-exp '/' negation-exp %prec /
| negation-exp
;
addition-exp: addition-exp '-' multiplication-exp %prec -
| addition-exp '+' multiplication-exp %prec +
| multiplication-exp
;
order-exp: addition-exp 'LESS-EQUAL' addition-exp %prec =
| addition-exp '<' addition-exp %prec =
| addition-exp 'GREATER-EQUAL' addition-exp %prec =
| addition-exp '>' addition-exp %prec =
| addition-exp 'NOT-EQUAL' addition-exp %prec =
| addition-exp '=' addition-exp %prec =
| addition-exp
;
logical-negation-exp: 'NEG' logical-negation-exp %prec NEG
| order-exp
;
assignment-exp: IDENTIFIER:= assignment-exp
| IDENTIFIEROP args 'CP' ':=' assignment-exp
| logical-negation-exp
;
compound-exp: compound-exp 'SEMI' assignment-exp
| assignment-exp
;
exp: compound-exp
;
%%

364
bracket/lang/parser.rkt Normal file
View File

@ -0,0 +1,364 @@
#lang racket
(require "parameter.rkt")
(require syntax/srcloc)
;;;
;;; NOTES:
;;; Changes from planet version: ]] (CDB) Bug fixed
;;; Strings are supported.
;;; Assignments changed from set! to define.
;;; Assignment of functions.
;;; Bug fix: identifiers with more than one _ wasn't converted correctly
; <e> = <num>
; | <string>
; | <id> variable reference
; | <e> [ <args> ] application
; | { <args> } list construction
; | <e> + <e> addition
; | <e> - <e> subtraction
; | <e> * <e> multiplication
; | <e> / <e> division
; | <e> ^ <e> exponentiation
; | - <e> negation
; | ( <e> ) grouping
; | <id> ( <args> ) := <e> function definition
; <id> An identifier begins with a letter,
; and is optionally followed by series of letters, digits or underscores.
; An underscore is converted to a -. Thus list_ref will refer to list-ref.
; <num> A number is an non-empty series of digits,
; optionally followed by a period followed by a series of digits.
; <string> A number is a " followed by a series of non-" characters followed by a " .
(provide parse-expression)
(require parser-tools/yacc
parser-tools/lex
(prefix-in : parser-tools/lex-sre)
syntax/readerr)
(define-tokens value-tokens (NUMBER STRING IDENTIFIER IDENTIFIEROP IDENTIFIER:=))
(define-empty-tokens
op-tokens
(newline
:=
OP CP ; ( )
CP:= ; ):=
OB CB ; [ ]
OC CC ; { }
ODB ; [[ ]]
COMMA ; ,
SEMI ; ;
PERIOD ; .
LAMBDA ; lambda or λ
SQRT ; √
NEG ; ¬ (logical negation)
LESS-EQUAL ; <= or ≤
GREATER-EQUAL ; >= or ≥
NOT-EQUAL ; <> or ≠
= < >
+ - * / ^
DEFINE
EOF))
(define-lex-abbrevs
[letter (:or (:/ "a" "z") (:/ #\A #\Z) )]
[digit (:/ #\0 #\9)]
[string (:: #\" (:* (:~ #\")) #\")]
[identifier (:: letter (:* (:or letter digit #\_ #\?)))]
[identifier:= (:: letter (:* (:or letter digit #\_ #\?)) ":=")]
[identifierOP (:: letter (:* (:or letter digit #\_ #\?)) "(")])
(define (string-drop-right n s)
(substring s 0 (- (string-length s) n)))
(define expression-lexer
(lexer-src-pos
[(eof) 'EOF]
[(:or #\tab #\space #\newline) ; this skips whitespace
(return-without-pos (expression-lexer input-port))]
[#\newline (token-newline)] ; (token-newline) returns 'newline
[(:or ":=" "+" "-" "*" "/" "^" "<" ">" "=" "\"") (string->symbol lexeme)]
["(" 'OP]
[")" 'CP]
["[" 'OB]
["]" 'CB]
["{" 'OC]
["}" 'CC]
["[[" 'ODB]
; ["]]" 'CDB]
["," 'COMMA]
[";" 'SEMI]
["." 'PERIOD]
[#\λ 'LAMBDA]
["lambda" 'LAMBDA]
["" 'SQRT]
["¬" 'NEG]
["" 'LESS-EQUAL]
["<=" 'LESS-EQUAL]
["" 'GREATER-EQUAL]
[">=" 'GREATER-EQUAL]
["<>" 'NOT-EQUAL]
["" 'NOT-EQUAL]
["define" 'DEFINE]
[string
(token-STRING (substring lexeme 1 (- (string-length lexeme) 1)))]
; The parser can only look ahead 1 token, so we have 3
; different identifiers to see whether := or ( comes after the identfier.
; This is enough to prevent shift/reduce conflicts between atom, definition,
; and application.
[identifier:=
(token-IDENTIFIER:=
(string->symbol (string-drop-right 2 (regexp-replace* #rx"_" lexeme "-"))))]
[identifierOP
(token-IDENTIFIEROP
(string->symbol (string-drop-right 1 (regexp-replace* #rx"_" lexeme "-"))))]
[identifier
(token-IDENTIFIER (string->symbol (regexp-replace* #rx"_" lexeme "-")))]
[(:+ digit) (token-NUMBER (string->number lexeme))]
[(:: (:+ digit) #\. (:* digit)) (token-NUMBER (string->number lexeme))]))
;; A macro to build the syntax object
(define-syntax (b stx)
(syntax-case stx ()
[(_ o value start end)
#'(b o value start end 0 0)]
[(_ o value start end start-adjust end-adjust)
(with-syntax
((start-pos (datum->syntax #'start
(string->symbol
(format "$~a-start-pos"
(syntax->datum #'start)))))
(end-pos (datum->syntax #'end
(string->symbol
(format "$~a-end-pos"
(syntax->datum #'end))))))
#`(datum->syntax
o
value
(list (if (syntax? o) (syntax-source o) 'missing-in-action--sorry)
(if (and o (syntax-line o))
(+ (syntax-line o) (position-line start-pos) start-adjust -1) #f)
(if (and o (syntax-column o))
(+ (syntax-column o) (position-offset start-pos) start-adjust) #f)
(if (and o (syntax-position o))
(+ (syntax-position o) (- (position-offset start-pos) start-adjust 1)) #f)
(- (+ (position-offset end-pos) end-adjust)
(+ (position-offset start-pos) start-adjust)))
o o))]))
; for testing: builds lists instead of syntax objects
#;(define-syntax (b stx)
(syntax-case stx ()
[(_ _ val _ _)
#'val]))
(define (display-position-token pos)
(display (position->list pos)))
(define (position->list pos)
(list (position-offset pos)
(position-line pos)
(position-col pos)))
(define source-name #f)
(define orig-stx #f)
(define o #f)
(define (expression-parser src-name orig)
(λ (gen)
(set! source-name src-name)
(set! orig-stx orig)
(set! o orig)
(the-parser gen)))
(define the-parser
(parser
(src-pos)
; (suppress) ; hmm...
;(debug "parser-dump.txt")
;(yacc-output "parser-dump.yacc")
(start start)
(end newline EOF)
(tokens value-tokens op-tokens)
(error (lambda (token-ok? name val start end)
; The first argument will be #f if and only if the error is that an invalid token was received.
; The second and third arguments will be the name and the value of the token at which the error was detected.
; The fourth and fifth arguments, if present, provide the source positions of that token.
#;(unless #f #; (string? (syntax->datum o))
(display "DEBUGXXX: ")
(display (list o token-ok? name val start end))
(display-position-token start) (newline)
(display-position-token end) (newline)
(displayln source-name)
(newline))
(error-print-source-location #t)
(displayln "Syntax error")
(raise-read-error
"Syntax error"
source-name
(position-line start)
(position-col start)
(position-offset start)
(+ (- (position-offset end) (position-offset start))))
#;(raise-syntax-error
#f
"syntax error"
(datum->syntax
#'here 'here
(list
source-name
(position-line start)
(position-col start)
(position-offset start)
(+ (- (position-offset end) (position-offset start))))))))
(precs ; (left :=)
; (right OP)
(left - +)
(left * /)
(right OB)
(right ^)
(left =) ; comparisons
(right NEG)
(left SEMI)
; (right IDENTIFIER)
)
(grammar
(start [(exp) (b o `(#%infix ,$1) 1 1)]
[() #f])
;; If there is an error, ignore everything before the error
;; and try to start over right after the error
(args [(exp) (b o (list $1) 1 1)]
[(exp COMMA args) (b o (cons $1 $3) 1 3)]
[() '()])
(ids [() '()]
[(IDENTIFIER ids) (b o (cons $1 $2) 1 2)])
(parenthensis-exp
[(OP exp CP) $2])
(atom
[(NUMBER) (b o $1 1 1)]
[(IDENTIFIER) (prec IDENTIFIER) (b o $1 1 1)]
[(STRING) (b o $1 1 1)]
[(parenthensis-exp) $1])
(construction-exp
[(OC args CC) (b o `(,(b o 'list 1 3) ,@$2) 1 3)]
[(OP LAMBDA ids PERIOD exp CP) (b o `(,(b o 'lambda 2 2) ,$3 ,$5) 1 6)]
[(atom) $1])
(application-exp
;[(application-exp OB args CB) (b o `(,$1 ,@$3) 1 4)] ; function application
; Due the extra ( in IDENTIFIEROP we need to adjust the end with -1.
[(IDENTIFIEROP args CP) (b o `(,(b o $1 1 1 0 -1) ,@$2) 1 3)] ; function application
[(application-exp OP args CP) (prec OP) (b o `(,$1 ,@$3) 1 4 )] ; function application
[(application-exp ODB exp CB CB) (b o `(,(b o 'list-ref 1 4) ,$1 ,$3) 1 4)] ; list ref
[(construction-exp) $1])
#;(implicit-exp
[(application-exp application-exp) (prec *) (b o `(,(b o '* 1 2) ,$1 ,$2) 1 2)] ; implicit
[(application-exp) $1])
(power-exp
[(application-exp ^ power-exp) (prec ^) (b o `(expt ,$1 ,$3) 1 3)]
[(application-exp) $1])
(sqrt-exp
[(SQRT sqrt-exp) (b o `(,(b o 'sqrt 1 1) ,$2) 1 2)]
[(power-exp) $1])
(negation-exp
[(- negation-exp) (b o `(,(b o '- 1 1) ,$2) 1 2)]
[(sqrt-exp) $1])
(multiplication-exp
[(multiplication-exp * negation-exp) (prec *) (b o `(,(b o '* 2 2) ,$1 ,$3) 1 3)]
[(multiplication-exp / negation-exp) (prec /) (b o `(,(b o '/ 2 2) ,$1 ,$3) 1 3)]
;[(multiplication-exp negation-exp) (prec *) (b o `(,(b o '* 1 2) ,$1 ,$2) 1 2)]
[(negation-exp) $1])
(addition-exp
[(addition-exp - multiplication-exp) (prec -) (b o `(,(b o '- 2 2) ,$1 ,$3) 1 3)]
[(addition-exp + multiplication-exp) (prec +) (b o `(,(b o '+ 2 2) ,$1 ,$3) 1 3)]
[(multiplication-exp) $1])
(order-exp
[(addition-exp LESS-EQUAL addition-exp) (prec =) (b o `(,(b o '<= 2 2) ,$1 ,$3) 1 3)]
[(addition-exp < addition-exp) (prec =) (b o `(,(b o '< 2 2) ,$1 ,$3) 1 3)]
[(addition-exp GREATER-EQUAL addition-exp) (prec =) (b o `(,(b o '>= 2 2) ,$1 ,$3) 1 3)]
[(addition-exp > addition-exp) (prec =) (b o `(,(b o '> 2 2) ,$1 ,$3) 1 3)]
[(addition-exp NOT-EQUAL addition-exp) (prec =) (b o `(not (,(b o '= 2 2) ,$1 ,$3)) 1 3)]
[(addition-exp = addition-exp) (prec =) (b o `(,(b o '= 2 2) ,$1 ,$3) 1 3)]
[(addition-exp) $1])
(logical-negation-exp
[(NEG logical-negation-exp) (prec NEG) (b o `(,(b o 'not 1 1) ,$2) 1 2)]
[(order-exp) $1])
; The no DEFINE version conflicts with application.
; Solution? Move definition with := into rule for application.
(assignment-exp
;[(DEFINE IDENTIFIER := assignment-exp) (b o `(,(b o 'define 3 3) ,$2 ,$4) 2 4)]
;[(DEFINE IDENTIFIER OP args CP := assignment-exp) (b o `(,(b o 'define 4 4) (,$2 ,@$4) ,$7) 2 6)]
[(IDENTIFIER:= assignment-exp) (b o `(,(b o 'define 1 1)
,(b o $1 1 1
; adjust end with -2 due to the chars in :=
0 -2)
,(b o $2 2 2)) 1 2)]
[(IDENTIFIEROP args CP := assignment-exp) (b o `(,(b o 'define 2 2) (,$1 ,@$2) ,$5) 1 5)]
[(logical-negation-exp) $1])
(compound-exp
[(compound-exp SEMI assignment-exp) (b o `(,(b o 'begin 2 2) ,$1 ,$3) 1 3)]
[(assignment-exp) $1])
(exp
[(compound-exp) $1]))))
(define (parse-expression src stx ip)
(port-count-lines! ip)
((expression-parser
(if src src (object-name ip))
; If you change any of these values, then
; you must change the builder b which uses
; the the values in here to add to newly read
; objects. If the lexer/parser was only to
; read from entire files, there would be no problem,
; but sometimes one must read from strings
; entered in a repl. There the syntax-objects must be
; adjusted.
(datum->syntax #f
'here
(list (if src src (object-name ip))
1 ; line 1
0 ; column 0
1 ; offset/position 1 (contract for datum->syntax requires a positive offset)
#f) ; span
)) ; no properties
; The following Tom Foolery is to needed to turn
; SEMI EOF into EOF
; This allows one to have an optional semi colon in the end of the file.
(let ([peek (expression-lexer ip)]
[peek1 (expression-lexer ip)])
(define (next)
(cond
[(eq? (position-token-token peek) 'EOF) (void)]
[else (set! peek peek1)
(set! peek1 (expression-lexer ip))]))
(λ ()
(if (and (eq? (position-token-token peek) 'SEMI)
(eq? (position-token-token peek1) 'EOF))
(begin0 peek1 (next))
(begin0 peek (next)))))))

51
bracket/lang/reader.rkt Normal file
View File

@ -0,0 +1,51 @@
#lang racket
(provide (rename-out
[my-read read]
[my-read-syntax read-syntax]))
(require "parser.rkt")
(require syntax/strip-context)
(define (my-read in)
(syntax->datum
(my-read-syntax #'from-my-read in)))
(define (my-read-syntax src in)
(if (eof-object? (peek-byte in))
eof
(with-syntax ([body (parse-expression
src
#'from-my-read-syntax in)])
(syntax-property
(strip-context
#'(module anything "bracket-lang.rkt"
(define-syntax (#%infix stx)
;(displayln (list 'my-read-syntax: stx))
(syntax-case stx ()
[(_ expr) #'expr]))
(require (submod "bracket.rkt" bracket)
(submod "bracket.rkt" symbolic-application))
; This lists the operators used by the parser.
(define expt Power)
(define + Plus)
(define - Minus)
(define * Times)
(define / Quotient)
(define = Equal)
(define sqrt Sqrt)
(define list List)
(define list-ref List-ref)
(define-syntax (define stx)
(syntax-case stx () [(_ . more) #'(Define . more)]))
body))
'module-language
'#(bracket/bracket-info get-language-info #f)))))
(define (get-info in mod line col pos)
(lambda (key default)
(case key
[(color-lexer)
(dynamic-require 'syntax-color/default-lexer
'default-lexer)]
[else default])))

View File

@ -0,0 +1,7 @@
#lang racket
(require "show.rkt")
(provide configure)
(define (configure data)
(show-enabled #t))

9
bracket/show.rkt Normal file
View File

@ -0,0 +1,9 @@
#lang racket
(provide show show-enabled)
(define show-enabled (make-parameter #f))
(define (show v)
(when (show-enabled)
(display v)))

View File

@ -0,0 +1,13 @@
#lang mpl
DeclareVars(x);
Graphics({Disk()});
Graphics({Disk({0,0})});
Graphics({Disk({0,0},5)});
Graphics({Red, Disk({0,0},6), Blue , Disk({8,0},6), Green, Disk({4,4},6)});
Graphics({Hue(0),Point({0,0}),Hue(1/3),Point({3,0}),Hue(2/3),Point({6,0})});
Graphics({Line({10,10},{20,20},{20,30},{30,30}),
Point({10,10})});
Graphics(AppendStar(Map((λx.{Hue(x/(2*pi)),Point({8*Sin(2*x),8*Cos(3*x)})}),Range(0,2*pi,1/128))))

View File

@ -0,0 +1,8 @@
#lang mpl
DeclareVars(x,y,t);
time(Expand((x+2*y+1)^5));
time(Expand((x+2*y+1)^5));
time(Expand((x+2*y+1)^5));

27
bracket/tests/testing.rkt Normal file
View File

@ -0,0 +1,27 @@
#lang bracket
DeclareVars(x,y,z,x0,y0,z0,w);
{2,3}*{4,5};
2*{3,4};
{3,4}*5;
Fold(f,b,xs):=foldl(f,b,rest(xs));
sum_list(xs):=Fold(Plus,0,xs);
RRange(i,j):=if(i>=j,{},Cons(i,Range(i+1,j)));
sum(f,x,i,j):=sum_list(Map((λk.Substitute(f,x=k)),Range(i,j)));
sum(x^2,x,1,4);
dot(v,w):=sum_list(v*w);
norm(v):=√(dot(v,v));
proj(v,w):=(dot(v,w)/(norm(w))^2)*w;
line(point,normal):=dot((point-{x,y}),normal);
a:={x,y};
b:={z,w};
bug_in_next_two_lines:=2;
a*b;
dot(a,b);
norm(a);
norm(b);
proj(a,b);
line({x0,y0},{z,w})

View File

@ -0,0 +1,13 @@
#lang mpl
DeclareVars(x,y,z,v,v1,v2,w,w1,w2,a,b,c);
sumlist(xs):=Apply(Plus,xs);
dot(v,w):=sumlist(v*w);
norm(v):=Sqrt(dot(v,v));
proj(v,w):=(dot(v,w)/norm(w))*w;
dot({a,b},{x,y});
norm({a,b});
(dot({a,b},{x,y})/norm({x,y})) * {x,y};
(dot({a,b,c},{x,y,z})/norm({x,y,z})) * {x,y,z};
proj({a,b},{x,y});

View File

@ -0,0 +1,15 @@
#lang mpl
DeclareVars(x,y);
{2}+x;
x+{3};
x+{4,5};
{4,5}+x;
{3,4}+{x,y};
{3,4,5}+{x,y};
{6}*x;
x*{7};
x*{8,9};
{10,11}*{x,y}

View File

@ -0,0 +1 @@
("5.3.0.6" ("aae85b364fdad2d22792dcc703d47d1c2f80d03f" . "503a738d74e318a813236a43fae9d2155ee7c3c2") (collects #"scribble" #"manual" #"lang.rkt") #"/Users/soegaard/Dropbox/GitHub/racket-cas/docs/../math-scribble/math-scribble.rkt" (collects #"scribble" #"manual" #"lang" #"reader.rkt"))

Binary file not shown.

View File

@ -0,0 +1 @@
("5.3.0.11" ("d0e0508b2e39ee46638efd465e60acfc1ae7a644" . "317ac9ad74dd16337305817c7ac273af3918dab8") (collects #"racket" #"base.rkt") (collects #"errortrace" #"errortrace-key.rkt") (collects #"scribble" #"base.rkt") (collects #"scribble" #"html-properties.rkt") (collects #"scribble" #"core.rkt") (collects #"racket" #"base" #"lang" #"reader.rkt"))

Binary file not shown.

9
docs/index.html Normal file
View File

@ -0,0 +1,9 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head><meta http-equiv="content-type" content="text-html; charset=utf-8" /><title>Racket Math Libraries</title><link rel="stylesheet" type="text/css" href="scribble.css" title="default" /><link rel="stylesheet" type="text/css" href="math-display.css" title="default" /><link rel="stylesheet" type="text/css" href="racket.css" title="default" /><link rel="stylesheet" type="text/css" href="scribble-style.css" title="default" /><script type="text/javascript" src="scribble-common.js"></script></head><body id="scribble-racket-lang-org"><div class="tocset"><div class="tocview"><div class="tocviewlist" style="margin-bottom: 1em;"><div class="tocviewtitle"><table cellspacing="0" cellpadding="0"><tr><td style="width: 1em;"><a href="javascript:void(0);" title="Expand/Collapse" class="tocviewtoggle" onclick="TocviewToggle(this,&quot;tocview_0&quot;);">&#9658;</a></td><td></td><td><a href="" class="tocviewselflink" pltdoc="x">Racket Math Libraries</a></td></tr></table></div><div class="tocviewsublistonly" style="display: none;" id="tocview_0"><table cellspacing="0" cellpadding="0"><tr><td align="right">1&nbsp;</td><td><a href="#(part._matrix)" class="tocviewlink" pltdoc="x">Matrix Library</a></td></tr><tr><td align="right"></td><td><a href="#(part._doc-index)" class="tocviewlink" pltdoc="x">Index</a></td></tr></table></div></div></div><div class="tocsub"><table class="tocsublist" cellspacing="0"><tr><td><span class="tocsublinknumber">1<tt>&nbsp;</tt></span><a href="#(part._matrix)" class="tocsubseclink" pltdoc="x">Matrix Library</a></td></tr><tr><td><span class="tocsublinknumber">1.1<tt>&nbsp;</tt></span><a href="#(part._.Example)" class="tocsubseclink" pltdoc="x">Example</a></td></tr><tr><td><span class="tocsublinknumber">1.2<tt>&nbsp;</tt></span><a href="#(part._.Constructors)" class="tocsubseclink" pltdoc="x">Constructors</a></td></tr><tr><td><span class="tocsublinknumber">1.3<tt>&nbsp;</tt></span><a href="#(part._.Comprehensions)" class="tocsubseclink" pltdoc="x">Comprehensions</a></td></tr><tr><td><span class="tocsublinknumber">1.4<tt>&nbsp;</tt></span><a href="#(part._.Unary_.Operators)" class="tocsubseclink" pltdoc="x">Unary Operators</a></td></tr><tr><td><span class="tocsublinknumber">1.5<tt>&nbsp;</tt></span><a href="#(part._.Binary_.Operators)" class="tocsubseclink" pltdoc="x">Binary Operators</a></td></tr><tr><td><span class="tocsublinknumber"></span><a href="#(part._doc-index)" class="tocsubseclink" pltdoc="x">Index</a></td></tr></table></div></div><div class="maincolumn"><div class="main"><div class="versionbox"><span class="versionNoNav">Version: 5.3.0.6</span></div><h2><a name="(part._.Racket_.Math_.Libraries)"></a>Racket Math Libraries</h2><div class="SAuthorListBox"><span class="SAuthorList"><p class="author">Jens Axel S&#248;gaard</p></span></div><p>These libraries is intended to become the backend for a CAS
written in Racket. A CAS requires libraries for a wide range
of mathematical concepts and algorithms.</p><p>The matrix library implements matrices over Racket numbers.
The implementation is written in Racket, that is there are no
external dependencies.</p><p>The development version of this library is available at Github:
<a href="https://github.com/soegaard">https://github.com/soegaard</a></p><table cellspacing="0"><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="#(part._matrix)" class="toptoclink" pltdoc="x">1<span class="hspace">&nbsp;</span>Matrix Library</a></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="#(part._.Example)" class="toclink" pltdoc="x">1.1<span class="hspace">&nbsp;</span>Example</a></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="#(part._.Constructors)" class="toclink" pltdoc="x">1.2<span class="hspace">&nbsp;</span>Constructors</a></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="#(part._.Comprehensions)" class="toclink" pltdoc="x">1.3<span class="hspace">&nbsp;</span>Comprehensions</a></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="#(part._.Unary_.Operators)" class="toclink" pltdoc="x">1.4<span class="hspace">&nbsp;</span>Unary Operators</a></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="#(part._.Binary_.Operators)" class="toclink" pltdoc="x">1.5<span class="hspace">&nbsp;</span>Binary Operators</a></p></td></tr><tr><td><p><span class="hspace"></span></p></td></tr><tr><td><p><span class="hspace">&nbsp;&nbsp;&nbsp;&nbsp;</span><a href="#(part._doc-index)" class="toptoclink" pltdoc="x">Index</a></p></td></tr></table><h3>1<tt>&nbsp;</tt><a name="(part._matrix)"></a>Matrix Library</h3><p>A matrix is a rectangular array of numbers. A matrix with
m rows and n columns is called an mxn-matrix.
<span class="MathDisplay">\[1+x \]</span></p><h4>1.1<tt>&nbsp;</tt><a name="(part._.Example)"></a>Example</h4><h4>1.2<tt>&nbsp;</tt><a name="(part._.Constructors)"></a>Constructors</h4><h4>1.3<tt>&nbsp;</tt><a name="(part._.Comprehensions)"></a>Comprehensions</h4><h4>1.4<tt>&nbsp;</tt><a name="(part._.Unary_.Operators)"></a>Unary Operators</h4><h4>1.5<tt>&nbsp;</tt><a name="(part._.Binary_.Operators)"></a>Binary Operators</h4><h3><a name="(part._doc-index)"></a>Index</h3><table cellspacing="0"><tr><td><p><span class="nonavigation">A</span> <a href="#alpha:B">B</a> <a href="#alpha:C">C</a> <span class="nonavigation">D</span> <a href="#alpha:E">E</a> <span class="nonavigation">F</span> <span class="nonavigation">G</span> <span class="nonavigation">H</span> <span class="nonavigation">I</span> <span class="nonavigation">J</span> <span class="nonavigation">K</span> <span class="nonavigation">L</span> <a href="#alpha:M">M</a> <span class="nonavigation">N</span> <span class="nonavigation">O</span> <span class="nonavigation">P</span> <span class="nonavigation">Q</span> <a href="#alpha:R">R</a> <span class="nonavigation">S</span> <span class="nonavigation">T</span> <a href="#alpha:U">U</a> <span class="nonavigation">V</span> <span class="nonavigation">W</span> <span class="nonavigation">X</span> <span class="nonavigation">Y</span> <span class="nonavigation">Z</span> </p></td></tr><tr><td><p>&nbsp;</p></td></tr><tr><td><p><a name="alpha:B"></a><span><a href="#(part._.Binary_.Operators)" class="indexlink" pltdoc="x">Binary Operators<br /></a></span><a name="alpha:C"></a><span><a href="#(part._.Comprehensions)" class="indexlink" pltdoc="x">Comprehensions<br /></a></span><a href="#(part._.Constructors)" class="indexlink" pltdoc="x">Constructors<br /></a><a name="alpha:E"></a><span><a href="#(part._.Example)" class="indexlink" pltdoc="x">Example<br /></a></span><a name="alpha:M"></a><span><a href="#(part._matrix)" class="indexlink" pltdoc="x">Matrix Library<br /></a></span><a name="alpha:R"></a><span><a href="" class="indexlink" pltdoc="x">Racket Math Libraries<br /></a></span><a name="alpha:U"></a><span><a href="#(part._.Unary_.Operators)" class="indexlink" pltdoc="x">Unary Operators<br /></a></span></p></td></tr></table></div></div><div id="contextindicator">&nbsp;</div></body></html>

BIN
docs/index.pdf Normal file

Binary file not shown.

21
docs/index.scrbl Normal file
View File

@ -0,0 +1,21 @@
#lang scribble/manual
@title{Racket Math Libraries}
@author["Jens Axel Søgaard"]
These libraries is intended to become the backend for a CAS
written in Racket. A CAS requires libraries for a wide range
of mathematical concepts and algorithms.
The matrix library implements matrices over Racket numbers.
The implementation is written in Racket, that is there are no
external dependencies.
The development version of this library is available at Github:
@(let ([url "https://github.com/soegaard"])
(link url url))
@table-of-contents[]
@; ------------------------------------------------------------------------
@include-section["matrix.scrbl"]
@index-section[]

2
docs/math-display.css Normal file
View File

@ -0,0 +1,2 @@
.MathDisplay {
}

4
docs/math-inline.css Normal file
View File

@ -0,0 +1,4 @@
.MathInline {
}

39
docs/matrix.html Normal file

File diff suppressed because one or more lines are too long

324
docs/matrix.scrbl Normal file
View File

@ -0,0 +1,324 @@
#lang scribble/manual
@(require ; "../math-scribble/math-scribble.rkt"
(for-label "../matrix.rkt"
racket
racket/contract
racket/dict
racket/base)
"../matrix.rkt"
racket/string
racket/list
scribble/eval
"pr-math.rkt")
@setup-math
@;@$$[(tex-matrix (matrix 2 3 1 2 3 4 5 6))]
@;@$$[(build-tex-matrix 2 3 (λ (i j) (format "a_{~a~a}" i j)))]
@(define (make-matrix-eval print-matrix-as-snip)
(let ([eval (make-base-eval)])
(eval `(begin
(require "../matrix.rkt"
slideshow/pict
"pr-math.rkt")
(begin
(require racket/list)
(define (subscript a i [j #f])
(if j
(hb-append (scale (text a) 2)
(scale (text (format "~a~a" i j)) 0.75))
(hb-append (scale (text a) 2)
(scale (text (format "~a" i)) 0.75))))
(define (a i j)
(subscript "a" i j))
(define (b i j)
(subscript "a" i j))
(define (add-brackets p)
(define bw 5)
(define bh 1)
(let ([h (pict-height p)])
(hc-append
; left bracket
(filled-rectangle 1 h)
(vl-append (filled-rectangle bw bh)
(blank bw (- h (* 2 bh)))
(filled-rectangle bw bh))
; contents
p
; right bracket
(vl-append (filled-rectangle bw bh)
(blank bw (- h (* 2 bh)))
(filled-rectangle bw bh))
(filled-rectangle 1 h))))
(define (build-array-pict m n f)
(apply hc-append
(add-between
(for/list ([j (in-range n)])
(apply vr-append
(for/list ([i (in-range m)])
(let ([f_ij (f i j)])
(cond
[(number? f_ij)
(text (number->string f_ij))]
[(pict? f_ij) f_ij]
[(string? f_ij)
(text f_ij)]
[else (error)])))))
(blank 5))))
(define (build-matrix-pict m n f)
(add-brackets
(build-array-pict m n f)))
(define (matrix->pict M)
(define-values (m n) (matrix-size M))
(add-brackets
(build-array-pict
m n (λ (i j) (matrix-ref M i j)))))
,(if print-matrix-as-snip
'(current-print
(let ([print (current-print)])
(define (maybe->matrix v)
(if (matrix? v) (matrix->pict v) v))
(λ (v) (print
(cond
[(matrix? v) (matrix->pict v)]
[(list? v) (map maybe->matrix v)]
[else v])))))
'(begin))
)))
eval))
@;@racketinput[(matrix 2 3 1 2 3 4 5 6)]
@;@$[(tex-matrix (matrix 2 3 1 2 3 4 5 6))]
@racketblock[> (matrix 2 3 1 2 3 4 5 6)
#,(math-in (tex-matrix (matrix 2 3 1 2 3 4 5 6)))]
@(define matrix-eval (make-matrix-eval #f))
@(define matrix-eval/snip (make-matrix-eval #t))
@;defmodulelang[@racketmodname[matrix] #:module-paths ("../matrix.rkt")]
@defmodule[(file "../matrix.rkt")]
@(define the-eval (make-base-eval))
@(the-eval '(require "../matrix.rkt"))
@title[#:tag "matrix"]{Matrix Library}
A @italic{matrix} is a rectangular array of numbers. A typical example:
@centered{
@interaction-eval-show[#:eval matrix-eval
(scale
(matrix->pict
(matrix 3 2 1 2 3 4 5 6)) 2)]}
The horizontal lines are called @italic{rows} and the vertical lines
are called @italic{columns}. The matrix above has @italic{m}=3 rows
and @italic{n}=2 columns and is an example of an @italic{3x2}-matrix.
In general a matrix with @italic{m} rows and @italic{n} columns is
called an @italic{mxn}-matrix.
Matrices with one row (1xn) only are called @italic{row vectors} and
matrices with one column (mx1) only are called @italic{column vectors}.
The @italic{entries} or @italic{elements} of a matrix is referred to by their
row and column number. In this library the row and columns are counted from 0.
@centered{
@interaction-eval-show[#:eval matrix-eval
(build-matrix-pict 3 2 (λ (i j) (a i j)))]}
Note: In standard mathematical notation row and column numbers are counted from 1.
@;-----------------------------------------------------------------------
@section{A basic example}
First require the libary:
@racketinput[(require "matrix.rkt")]
Create a 2x3 matrix with entries 1, 2, 3, 4, 5, and, 6.
@interaction[#:eval matrix-eval
(matrix 2 3 1 2 3 4 5 6)]
Display the matrix as a picture:
@interaction[#:eval matrix-eval
(matrix->pict
(matrix 2 3 1 2 3 4 5 6))]
Let's change the print handler, so we don't need to call @racket{matrix->pict}
ourselves.
@interaction[#:eval matrix-eval
(current-print
(let ([print (current-print)])
(λ (v) (print (if (matrix? v) (matrix->pict v) v)))))
(matrix 2 2 1 2 3 4)]
The basic operations are addition, subtraction and multiplication.
@interaction[#:eval matrix-eval/snip
(define A (matrix 2 2 1 2 3 4))
(define B (matrix 2 2 1 -2 3 -4))
A
B
(matrix-add A B)
(matrix-sub A B)
(matrix-mul A B)]
Scale a matrix by a factor 2.
@interaction[#:eval matrix-eval/snip
(matrix-scale 2 (matrix 2 2 1 2 3 4))]
Multiply a matrix on a column-vector.
@interaction[#:eval matrix-eval/snip
(matrix-mul (matrix 2 2 1 2 3 4)
(column-vector 1 0))]
@;---------------------------------------------------------------------
@section[#:tag "matrix constructors"]{Constructors}
@defproc[(matrix [m index/c] [n index/c] [x number?] ...)
matrix
]{
Construct a mxn-matrix with elements @racket[x ...].
@interaction[#:eval matrix-eval/snip
(matrix 2 2 1 2 3 4)]}
@defproc[(row-vector [x number?] ...)
matrix]{
Construct a row vector (a 1xn-matrix) with elements @racket[x ...].
@interaction[#:eval matrix-eval/snip
(row-vector 1 2 3)]}
@defproc[(column-vector [x number?] ...)
matrix]{
Construct a column vector (a mx1-matrix) with elements @racket[x ...].
@interaction[#:eval matrix-eval/snip
(column-vector 1 2 3)]}
@defproc[(make-matrix [m size/c] [n size/c] [x number?])
matrix]{
Construct a mxn-matrix where all entries are @racket[x].
@interaction[#:eval matrix-eval/snip
(make-matrix 2 3 4)]
}
@defproc[(build-matrix [m size/c] [n size/c] [f (index/c index/c -> number?)])
matrix]{
Construct a mxn-matrix where element (i,j) is @racket[(f i j)].
@interaction[#:eval matrix-eval/snip
(build-matrix 3 4 +)]
}
@defproc[(submatrix [M matrix?] [i index/c] [j index/c] [m size/c] [n size/c])
matrix]{
Construct a mxn-matrix with elements from row i to i+m and from column j to j+m.
@interaction[#:eval matrix-eval/snip
(define A (build-matrix 5 5 (λ (i j) (+ (* i 5) j))))
A
(submatrix A 2 3 1 2)]
}
@defproc[(matrix-augment [M matrix?] [N matrix?])
matrix]{
Augment the matrices M and N by "appending" their columns.
The number of rows in M and N must be the same.
@interaction[#:eval matrix-eval/snip
(matrix-augment (matrix 2 2 1 2
3 4)
(matrix 2 3 5 6 7
8 9 10))]
}
@defproc[(matrix-augment* [Ms (listof matrix?)])
matrix]{
Augment the matrices in the list Ms "appending" their columns.
The number of rows in alle the matrices must be the same.
@interaction[#:eval matrix-eval/snip
(matrix-augment* (list (matrix 2 1 1 2)
(matrix 2 1 3 4)
(matrix 2 1 5 6)))]
}
@defproc[(matrix-copy [M matrix?])
matrix]{
Copy the matrix M.
@interaction[#:eval matrix-eval/snip
(matrix-copy (matrix 1 2 3 4))]
}
@defproc[(matrix-row [M matrix?] [i index/c])
matrix]{
Construct a row vector from the i'th column of M.
@interaction[#:eval matrix-eval/snip
(define M (matrix 2 4 1 2 3 4 5 6 7 8))
M
(matrix-row M 1)]
}
@defproc[(matrix-column [M matrix?] [j index/c])
matrix]{
Construct a column vector from the j'th column of M.
@interaction[#:eval matrix-eval/snip
(define M (matrix 2 4 1 2 3 4 5 6 7 8))
M
(matrix-column M 2)]
}
@defproc*[([(matrix-identity [m size/c]) matrix]
[(matrix-identity [m size/c] [n size/c]) matrix])]{
Return m x n matrix with ones on the diagonal and zeros elsewhere.
If only one argument is given, a square matrix is produced.
@interaction[#:eval matrix-eval/snip
(matrix-identity 3)
(matrix-identity 3 2)]
}
@defproc[(matrix-diagonal [xs (listof number?)])
matrix]{
Construct a square matrix with elements from xs on the diagonal and 0 elsewhere.
@interaction[#:eval matrix-eval/snip
(matrix-diagonal '(1 2 3))]
}
@section[#:tag "matrix operations"]{Operations}
@defproc[(matrix-scale [s number?] [M matrix?])
matrix]{
Multiply each element of M with s.
@interaction[#:eval matrix-eval/snip
(matrix-scale 3 (matrix 2 2 1 2 3 4))]
}
@defproc[(matrix-add [M matrix?] [N matrix?])
matrix]{
Return the sum of M and N.
@interaction[#:eval matrix-eval/snip
(define M (matrix 2 2 1 2 3 4))
(define N (matrix 2 2 1 -2 3 -4))
(list M N (matrix-add M N))]
}
@defproc[(matrix-mul [M matrix?] [N matrix?])
matrix]{
Return the product of M and N.
The number of columns in M must be equal to the number of rows in N.
@interaction[#:eval matrix-eval/snip
(define M (matrix 2 2 1 2 3 4))
(define N (matrix 2 2 2 0 0 1))
(list M N (matrix-mul M N))]
}
@defproc[(matrix-linear [a number?] [M matrix?] [b number?] [N matrix?])
matrix]{
Return the linear combination of M and N @math-in{a*M + b*N}.
@interaction[#:eval matrix-eval/snip
(define M (matrix 2 2 1 1 1 0))
(define N (matrix 2 2 0 0 1 1))
(list M N (matrix-linear -1 M 2 N))]
}
@section[#:tag "matrix unary operators"]{Unary Operators}
@section[#:tag "matrix comprehensions"]{Comprehensions}
@section{Binary Operators}

BIN
docs/pict.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
docs/pict_10.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 B

BIN
docs/pict_11.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 393 B

BIN
docs/pict_12.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 475 B

BIN
docs/pict_13.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 B

BIN
docs/pict_14.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1021 B

BIN
docs/pict_15.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
docs/pict_16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

BIN
docs/pict_17.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
docs/pict_18.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 698 B

BIN
docs/pict_19.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 B

BIN
docs/pict_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
docs/pict_20.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 908 B

BIN
docs/pict_21.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 586 B

BIN
docs/pict_22.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 B

BIN
docs/pict_23.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 B

BIN
docs/pict_24.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 B

BIN
docs/pict_25.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 701 B

BIN
docs/pict_26.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 B

BIN
docs/pict_27.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 533 B

BIN
docs/pict_28.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 546 B

BIN
docs/pict_29.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 B

BIN
docs/pict_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 676 B

BIN
docs/pict_30.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 B

BIN
docs/pict_31.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 B

BIN
docs/pict_4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 527 B

BIN
docs/pict_5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 554 B

BIN
docs/pict_6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 B

BIN
docs/pict_7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 604 B

BIN
docs/pict_8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 695 B

BIN
docs/pict_9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 B

36
docs/pr-math.rkt Normal file
View File

@ -0,0 +1,36 @@
#lang racket/base
; From http://con.racket-lang.org/pr-slides.pdf
; by Prabhakar Ragde
(require scribble/html-properties
scribble/base
scribble/core)
(provide setup-math math-in math-disp $ $$)
(define mathjax-source
"http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"
; "http://c328740.r40.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=default"
;"http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-HTML"
)
(define setup-math
(paragraph
(style
#f (list (alt-tag "script")
(attributes `((type . "text/javascript")
(src . ,mathjax-source )))))
'()))
(define (mymath start end . strs)
(make-element (make-style "relax" '(exact-chars)) `(,start ,@strs ,end)))
(define (math-in . strs)
(apply mymath "\\(" "\\)" strs))
(define (math-disp . strs)
(apply mymath "\\[" "\\]" strs))
(define $ math-in)
(define $$ math-disp)

201
docs/racket.css Normal file
View File

@ -0,0 +1,201 @@
/* See the beginning of "scribble.css". */
/* Monospace: */
.RktIn, .RktRdr, .RktPn, .RktMeta,
.RktMod, .RktKw, .RktVar, .RktSym,
.RktRes, .RktOut, .RktCmt, .RktVal {
font-family: monospace;
white-space: inherit;
}
/* Serif: */
.inheritedlbl {
font-family: serif;
}
/* ---------------------------------------- */
/* Inherited methods, left margin */
.inherited {
width: 100%;
margin-top: 0.5em;
text-align: left;
background-color: #ECF5F5;
}
.inherited td {
font-size: 82%;
padding-left: 1em;
text-indent: -0.8em;
padding-right: 0.2em;
}
.inheritedlbl {
font-style: italic;
}
/* ---------------------------------------- */
/* Racket text styles */
.RktIn {
color: #cc6633;
background-color: #eeeeee;
}
.RktInBG {
background-color: #eeeeee;
}
.RktRdr {
}
.RktPn {
color: #843c24;
}
.RktMeta {
color: black;
}
.RktMod {
color: black;
}
.RktOpt {
color: black;
}
.RktKw {
color: black;
/* font-weight: bold; */
}
.RktErr {
color: red;
font-style: italic;
}
.RktVar {
color: #262680;
font-style: italic;
}
.RktSym {
color: #262680;
}
.RktValLink {
text-decoration: none;
color: blue;
}
.RktModLink {
text-decoration: none;
color: blue;
}
.RktStxLink {
text-decoration: none;
color: black;
/* font-weight: bold; */
}
.RktRes {
color: #0000af;
}
.RktOut {
color: #960096;
}
.RktCmt {
color: #c2741f;
}
.RktVal {
color: #228b22;
}
/* ---------------------------------------- */
/* Some inline styles */
.together {
width: 100%;
}
.prototype, .argcontract, .RBoxed {
white-space: nowrap;
}
.prototype td {
vertical-align: text-top;
}
.longprototype td {
vertical-align: bottom;
}
.RktBlk {
white-space: inherit;
text-align: left;
}
.RktBlk tr {
white-space: inherit;
}
.RktBlk td {
vertical-align: baseline;
white-space: inherit;
}
.argcontract td {
vertical-align: text-top;
}
.highlighted {
background-color: #ddddff;
}
.defmodule {
width: 100%;
background-color: #F5F5DC;
}
.specgrammar {
float: right;
}
.RBibliography td {
vertical-align: text-top;
}
.leftindent {
margin-left: 1em;
margin-right: 0em;
}
.insetpara {
margin-left: 1em;
margin-right: 1em;
}
.Rfilebox {
}
.Rfiletitle {
text-align: right;
margin: 0em 0em 0em 0em;
}
.Rfilename {
border-top: 1px solid #6C8585;
border-right: 1px solid #6C8585;
padding-left: 0.5em;
padding-right: 0.5em;
background-color: #ECF5F5;
}
.Rfilecontent {
margin: 0em 0em 0em 0em;
}

153
docs/scribble-common.js Normal file
View File

@ -0,0 +1,153 @@
// Common functionality for PLT documentation pages
// Page Parameters ------------------------------------------------------------
var page_query_string =
(location.href.search(/\?([^#]+)(?:#|$)/) >= 0) && RegExp.$1;
var page_args =
((function(){
if (!page_query_string) return [];
var args = page_query_string.split(/[&;]/);
for (var i=0; i<args.length; i++) {
var a = args[i];
var p = a.indexOf('=');
if (p >= 0) args[i] = [a.substring(0,p), a.substring(p+1)];
else args[i] = [a, false];
}
return args;
})());
function GetPageArg(key, def) {
for (var i=0; i<page_args.length; i++)
if (page_args[i][0] == key) return unescape(page_args[i][1]);
return def;
}
function MergePageArgsIntoLink(a) {
if (page_args.length == 0 ||
(!a.attributes["pltdoc"]) || (a.attributes["pltdoc"].value == ""))
return;
a.href.search(/^([^?#]*)(?:\?([^#]*))?(#.*)?$/);
if (RegExp.$2.length == 0) {
a.href = RegExp.$1 + "?" + page_query_string + RegExp.$3;
} else {
// need to merge here, precedence to arguments that exist in `a'
var i, j;
var prefix = RegExp.$1, str = RegExp.$2, suffix = RegExp.$3;
var args = str.split(/[&;]/);
for (i=0; i<args.length; i++) {
j = args[i].indexOf('=');
if (j) args[i] = args[i].substring(0,j);
}
var additions = "";
for (i=0; i<page_args.length; i++) {
var exists = false;
for (j=0; j<args.length; j++)
if (args[j] == page_args[i][0]) { exists = true; break; }
if (!exists) str += "&" + page_args[i][0] + "=" + page_args[i][1];
}
a.href = prefix + "?" + str + suffix;
}
}
// Cookies --------------------------------------------------------------------
function GetCookie(key, def) {
var i, cookiestrs;
try {
if (document.cookie.length <= 0) return def;
cookiestrs = document.cookie.split(/; */);
} catch (e) { return def; }
for (i = 0; i < cookiestrs.length; i++) {
var cur = cookiestrs[i];
var eql = cur.indexOf('=');
if (eql >= 0 && cur.substring(0,eql) == key)
return unescape(cur.substring(eql+1));
}
return def;
}
function SetCookie(key, val) {
var d = new Date();
d.setTime(d.getTime()+(365*24*60*60*1000));
try {
document.cookie =
key + "=" + escape(val) + "; expires="+ d.toGMTString() + "; path=/";
} catch (e) {}
}
// note that this always stores a directory name, ending with a "/"
function SetPLTRoot(ver, relative) {
var root = location.protocol + "//" + location.host
+ NormalizePath(location.pathname.replace(/[^\/]*$/, relative));
SetCookie("PLT_Root."+ver, root);
}
// adding index.html works because of the above
function GotoPLTRoot(ver, relative) {
var u = GetCookie("PLT_Root."+ver, null);
if (u == null) return true; // no cookie: use plain up link
// the relative path is optional, default goes to the toplevel start page
if (!relative) relative = "index.html";
location = u + relative;
return false;
}
// Utilities ------------------------------------------------------------------
normalize_rxs = [/\/\/+/g, /\/\.(\/|$)/, /\/[^\/]*\/\.\.(\/|$)/];
function NormalizePath(path) {
var tmp, i;
for (i = 0; i < normalize_rxs.length; i++)
while ((tmp = path.replace(normalize_rxs[i], "/")) != path) path = tmp;
return path;
}
// `noscript' is problematic in some browsers (always renders as a
// block), use this hack instead (does not always work!)
// document.write("<style>mynoscript { display:none; }</style>");
// Interactions ---------------------------------------------------------------
function DoSearchKey(event, field, ver, top_path) {
var val = field.value;
if (event && event.keyCode == 13) {
var u = GetCookie("PLT_Root."+ver, null);
if (u == null) u = top_path; // default: go to the top path
u += "search/index.html?q=" + escape(val);
if (page_query_string) u += "&" + page_query_string;
location = u;
return false;
}
return true;
}
function TocviewToggle(glyph, id) {
var s = document.getElementById(id).style;
var expand = s.display == "none";
s.display = expand ? "block" : "none";
glyph.innerHTML = expand ? "&#9660;" : "&#9658;";
}
// Page Init ------------------------------------------------------------------
// Note: could make a function that inspects and uses window.onload to chain to
// a previous one, but this file needs to be required first anyway, since it
// contains utilities for all other files.
var on_load_funcs = [];
function AddOnLoad(fun) { on_load_funcs.push(fun); }
window.onload = function() {
for (var i=0; i<on_load_funcs.length; i++) on_load_funcs[i]();
};
AddOnLoad(function(){
var links = document.getElementsByTagName("a");
for (var i=0; i<links.length; i++) MergePageArgsIntoLink(links[i]);
var label = GetPageArg("ctxtname",false);
if (!label) return;
var indicator = document.getElementById("contextindicator");
if (!indicator) return;
indicator.innerHTML = label;
indicator.style.display = "block";
});

0
docs/scribble-style.css Normal file
View File

466
docs/scribble.css Normal file
View File

@ -0,0 +1,466 @@
/* CSS seems backward: List all the classes for which we want a
particular font, so that the font can be changed in one place. (It
would be nicer to reference a font definition from all the places
that we want it.)
As you read the rest of the file, remember to double-check here to
see if any font is set. */
/* Monospace: */
.maincolumn, .refpara, .refelem, .tocset, .stt, .hspace, .refparaleft, .refelemleft {
font-family: monospace;
}
/* Serif: */
.main, .refcontent, .tocview, .tocsub, i {
font-family: serif;
}
/* Sans-serif: */
.version, .versionNoNav {
font-family: sans-serif;
}
/* ---------------------------------------- */
p, .SIntrapara {
display: block;
margin: 1em 0;
}
h2 { /* per-page main title */
margin-top: 0;
}
h3, h4, h5, h6, h7, h8 {
margin-top: 1.75em;
margin-bottom: 0.5em;
}
/* Needed for browsers like Opera, and eventually for HTML 4 conformance.
This means that multiple paragraphs in a table element do not have a space
between them. */
table p {
margin-top: 0;
margin-bottom: 0;
}
/* ---------------------------------------- */
/* Main */
body {
color: black;
background-color: #ffffff;
}
table td {
padding-left: 0;
padding-right: 0;
}
.maincolumn {
width: 43em;
margin-right: -40em;
margin-left: 15em;
}
.main {
text-align: left;
}
/* ---------------------------------------- */
/* Navigation */
.navsettop, .navsetbottom {
background-color: #f0f0e0;
padding: 0.25em 0 0.25em 0;
}
.navsettop {
margin-bottom: 1.5em;
border-bottom: 2px solid #e0e0c0;
}
.navsetbottom {
margin-top: 2em;
border-top: 2px solid #e0e0c0;
}
.navleft {
margin-left: 1ex;
position: relative;
float: left;
white-space: nowrap;
}
.navright {
margin-right: 1ex;
position: relative;
float: right;
white-space: nowrap;
}
.nonavigation {
color: #e0e0e0;
}
.searchform {
display: inline;
margin: 0;
padding: 0;
}
.searchbox {
width: 16em;
margin: 0px;
padding: 0px;
background-color: #eee;
border: 1px solid #ddd;
text-align: center;
vertical-align: middle;
}
#contextindicator {
position: fixed;
background-color: #c6f;
color: #000;
font-family: monospace;
font-weight: bold;
padding: 2px 10px;
display: none;
right: 0;
bottom: 0;
}
/* ---------------------------------------- */
/* Version */
.versionbox {
position: relative;
float: right;
left: 2em;
height: 0em;
width: 13em;
margin: 0em -13em 0em 0em;
}
.version {
font-size: small;
}
.versionNoNav {
font-size: xx-small; /* avoid overlap with author */
}
/* ---------------------------------------- */
/* Margin notes */
.refpara, .refelem {
position: relative;
float: right;
left: 2em;
height: 0em;
width: 13em;
margin: 0em -13em 0em 0em;
}
.refpara, .refparaleft {
top: -1em;
}
.refcolumn {
background-color: #F5F5DC;
display: block;
position: relative;
width: 13em;
font-size: 85%;
border: 0.5em solid #F5F5DC;
margin: 0 0 0 0;
}
.refcontent {
margin: 0 0 0 0;
}
.refcontent p {
margin-top: 0;
margin-bottom: 0;
}
.refparaleft {
position: relative;
float: left;
right: 2em;
height: 0em;
width: 13em;
margin: 0em 0em 0em -13em;
}
.refcolumnleft, .refelemleft {
background-color: #F5F5DC;
display: block;
position: relative;
width: 13em;
font-size: 85%;
border: 0.5em solid #F5F5DC;
margin: 0 0 0 0;
}
/* ---------------------------------------- */
/* Table of contents, inline */
.toclink {
text-decoration: none;
color: blue;
font-size: 85%;
}
.toptoclink {
text-decoration: none;
color: blue;
font-weight: bold;
}
/* ---------------------------------------- */
/* Table of contents, left margin */
.tocset {
position: relative;
float: left;
width: 12.5em;
margin-right: 2em;
}
.tocset td {
vertical-align: text-top;
}
.tocview {
text-align: left;
background-color: #f0f0e0;
}
.tocsub {
text-align: left;
margin-top: 0.5em;
background-color: #f0f0e0;
}
.tocviewlist, .tocsublist {
margin-left: 0.2em;
margin-right: 0.2em;
padding-top: 0.2em;
padding-bottom: 0.2em;
}
.tocviewlist table {
font-size: 82%;
}
.tocviewsublist, .tocviewsublistonly, .tocviewsublisttop, .tocviewsublistbottom {
margin-left: 0.4em;
border-left: 1px solid #bbf;
padding-left: 0.8em;
}
.tocviewsublist {
margin-bottom: 1em;
}
.tocviewsublist table,
.tocviewsublistonly table,
.tocviewsublisttop table,
.tocviewsublistbottom table {
font-size: 75%;
}
.tocviewtitle * {
font-weight: bold;
}
.tocviewlink {
text-decoration: none;
color: blue;
}
.tocviewselflink {
text-decoration: underline;
color: blue;
}
.tocviewtoggle {
text-decoration: none;
color: blue;
font-size: 75%; /* looks better, and avoids bounce when toggling sub-sections due to font alignments */
}
.tocsublist td {
padding-left: 1em;
text-indent: -1em;
}
.tocsublinknumber {
font-size: 82%;
}
.tocsublink {
font-size: 82%;
text-decoration: none;
}
.tocsubseclink {
font-size: 82%;
text-decoration: none;
}
.tocsubnonseclink {
font-size: 82%;
text-decoration: none;
padding-left: 0.5em;
}
.tocsubtitle {
font-size: 82%;
font-style: italic;
margin: 0.2em;
}
.sepspace {
font-size: 40%;
}
.septitle {
font-size: 70%;
}
/* ---------------------------------------- */
/* Some inline styles */
.indexlink {
text-decoration: none;
}
.nobreak {
white-space: nowrap;
}
.stt {
}
.title {
font-size: 200%;
font-weight: normal;
margin-top: 2.8em;
text-align: center;
}
pre { margin-left: 2em; }
blockquote { margin-left: 2em; }
ol { list-style-type: decimal; }
ol ol { list-style-type: lower-alpha; }
ol ol ol { list-style-type: lower-roman; }
ol ol ol ol { list-style-type: upper-alpha; }
i {
}
.SCodeFlow {
display: block;
margin-left: 1em;
margin-bottom: 0em;
margin-right: 1em;
margin-top: 0em;
white-space: nowrap;
}
.SVInsetFlow {
display: block;
margin-left: 0em;
margin-bottom: 0em;
margin-right: 0em;
margin-top: 0em;
}
.SubFlow {
display: block;
margin: 0em;
}
.boxed {
width: 100%;
background-color: #E8E8FF;
}
.hspace {
}
.slant {
font-style: oblique;
}
.badlink {
text-decoration: underline;
color: red;
}
.plainlink {
text-decoration: none;
color: blue;
}
.techoutside { text-decoration: underline; color: #b0b0b0; }
.techoutside:hover { text-decoration: underline; color: blue; }
/* .techinside:hover doesn't work with FF, .techinside:hover>
.techinside doesn't work with IE, so use both (and IE doesn't
work with inherit in the second one, so use blue directly) */
.techinside { color: black; }
.techinside:hover { color: blue; }
.techoutside:hover>.techinside { color: inherit; }
.SCentered {
text-align: center;
}
.imageleft {
float: left;
margin-right: 0.3em;
}
.Smaller{
font-size: 82%;
}
.Larger{
font-size: 122%;
}
/* A hack, inserted to break some Scheme ids: */
.mywbr {
width: 0;
font-size: 1px;
}
.compact li p {
margin: 0em;
padding: 0em;
}
.noborder img {
border: 0;
}
.SAuthorListBox {
position: relative;
float: right;
left: 2em;
top: -2.5em;
height: 0em;
width: 13em;
margin: 0em -13em 0em 0em;
}
.SAuthorList {
font-size: 82%;
}
.SAuthorList:before {
content: "by ";
}
.author {
display: inline;
white-space: nowrap;
}

5460
graphics/graphics.rkt Normal file

File diff suppressed because it is too large Load Diff

168
gui/math-pict.rkt Normal file
View File

@ -0,0 +1,168 @@
#lang racket
(require slideshow/pict
slideshow)
(define (pict->snip p [scale-factor 5])
(pict->bitmap
(scale p scale-factor)))
(define (left-bracket content-height line-width bracket-width)
(define h content-height)
(define bw bracket-width)
(define lw line-width)
(hc-append
(filled-rectangle lw h)
(vl-append (filled-rectangle bw lw)
(blank bw (- h (* 2 lw)))
(filled-rectangle bw lw))))
(define (right-bracket content-height line-width bracket-width)
(define h content-height)
(define bw bracket-width)
(define lw line-width)
(hc-append
(vl-append (filled-rectangle bw lw)
(blank bw (- h (* 2 lw)))
(filled-rectangle bw lw))
(filled-rectangle lw h)))
;;; Combiners
(define (over p q)
(vc-append -4 q p))
(define (under p q)
(vc-append p q))
(define (left p q)
(hc-append q p))
(define (right p q)
(hc-append p q))
(define (subscript p q)
(hb-append p (scale q 5/12)))
(define (superscript p q)
(ht-append p (scale q 5/12)))
(define (fraction p q)
(define w (max (pict-width p) (pict-width q)))
(vc-append p (hc-append (blank 1 0) (hline w 1) (blank 1 0)) q))
;;; Elements depending on one pict
(define (vector-arrow p)
(arrow (pict-width p) 0))
(define (bar p)
(define w (pict-width p))
(clip-descent
(hc-append (blank 1 0)
(hline w 1)
(blank 1 0))))
;;; Combination
(define (add f c p)
; (add bar over p) will put a bar over p
(c p (f p)))
;;;
(define (add-brackets p)
(define lw 1)
(define bw 5)
(define h (pict-height p))
(hc-append
(left-bracket h lw bw)
p
(right-bracket h lw bw)))
(define (build-array-pict m n f)
(apply hc-append
(add-between
(for/list ([j (in-range n)])
(apply vr-append
(for/list ([i (in-range m)])
(let ([f_ij (f i j)])
(cond
[(number? f_ij)
(text (number->string f_ij))]
[(pict? f_ij) f_ij]
[(string? f_ij)
(text f_ij)]
[else (error)])))))
(blank 5))))
(require racket/gui/base)
(define (butt-hline w)
(dc
(λ (dc dx dy)
(define pen (send dc get-pen))
(send dc set-pen (send the-pen-list find-or-create-pen
(send pen get-color)
(send pen get-width)
'solid
'butt))
(send dc draw-line dx dy (+ dx w) dy)
(send dc set-pen pen))
w 1))
(define (left-paren p)
(define w (max 5 (ceiling (/ (pict-height p) 10))))
(define h (pict-height p))
(dc
(λ (dc dx dy)
(define pen (send dc get-pen))
(send dc set-pen
(send the-pen-list find-or-create-pen
(send pen get-color)
(send pen get-width)
'solid
'butt))
(send dc draw-arc (+ dx (/ w 2)) dy w h (/ pi 2) (* 3/2 pi))
(send dc set-pen pen))
w h))
(define (right-paren p)
(define w (max 5 (ceiling (/ (pict-height p) 10))))
(define h (pict-height p))
(dc
(λ (dc dx dy)
(define pen (send dc get-pen))
(send dc set-pen
(send the-pen-list find-or-create-pen
(send pen get-color)
(send pen get-width)
'solid
'butt))
(send dc draw-arc (- dx (/ w 2)) dy w h (* 3/2 pi) (/ pi 2))
(send dc set-pen pen))
w h))
(define (add-paren p)
(hc-append (left-paren p) p (right-paren p)))
;;; TESTS
; A 4x4 matrix
(scale
(add-brackets
(build-array-pict
4 4 (λ (i j) (subscript (text "a") (text (format "~a~a" i j))))))
5)
; bars
(scale (add bar over (text "a")) 5)
; fraction
(scale (fraction (text "x") (text "y")) 5)

655
gui/racket-cas.rkt Normal file
View File

@ -0,0 +1,655 @@
#lang racket
;;; Instructions:
;; 1. Use ctrl+m to insert a math box
;; 2. Write an infix expression in the math box. Evaluate with enter. [Use shift+enter to insert line breaks]
;; 3. E.g. write plot[sin] to draw a graph of sine.
;; Examples:
;; x_min[-pi]; x_max[pi];
;; y_min[-pi]; y_max[pi];
;; map[ (λk.plot[(λx.cos[x+k*pi/4])]),
;; {-4,-3,-2,-1,0,1,2,3,4}]; "done"
;;
;; TODO
;;
;; Editor: Bold and italic used more than once should toggle.
;; Editor: Text size.
;; Editor: Save and load.
;; Editor: When inserting part copied from MathBox, automatically insert new MathBox.
;; Parser: Extend f(x):=expr syntax to 2 or more variables.
;; Evaluation: Get syntax-location from math-text%
;; Keymaps: Insertion of greek, and, mathematical characters.
;; Maxima: Maxima backend. See send-lisp-command and receive-list in maxima.rkt.
;; Yacas: ?
;; LaTeX:
;; PlotCanvas: Add status icons in upper, left corner. Add zooms.
;; Plot: Error message for the case plot[not-a-function] (partially done - 0 is plotted)
;; MathBox: When to remove old evaluation result?
;; NSolve: Root polishing algorithms. See GSL.
;; Snips: Right-click menu: Options such output on/off.
;; Snips: Represent equations, integrals etc with small graphs ala Wolfram Alpha.
;; Educational: Recognize standard equations and offer step by step solutions.
;; LIMBO
;; PlotCanvas: Add "copy plot as image". set-clipboard-image is unimplmented :-(
;; (Fixed on OS X)
;; DONE
;;
;; MathBox: Evaluating an expression with an error, removes previous result.
;; MathBox: Enter evaluates. Shift+enter inserts newline.
;; Parser: plot[function[sin]] Handle parsing of ]] better
;; Parser: Declare variable: The operator := now expands to define
;; Parser: f(x):=expr now defines one variable functions
;; Parser: Handle - in names. _ is converted to -
;; Editor: Keybinding for bold and italic work.
;; Editor: Keybindings for λ α β γ δ ε ∆ Λ.
;; Editor: Gets focus right after start.
;; Plot: Parameters x-min, x-max, y-min, y-max for plot window.
;; Plot: Function/macro plot[...] introduced.
;; Plot: Added plot-horizontal-line and plot-vertical-line.
;; Plot: Remove old plots when reevaluating math boxes.
;; Plot: Different colors are used, when the user doesn't specify a color.
;; NSolve: Implemented bisection and Brent.
;; Snips: Right-click menu: Evaluation options such output on/off.
;; Errors: Errors and warnings can be signaled with user-error and user-warning
;; IDEAS
;; Behaviour when dragging parabolas and lines.
;; http://www.geogebra.org/forum/viewtopic.php?f=22&t=27113
(require racket/gui framework
(except-in plot plot points)
(prefix-in plot: plot)
"infix/main.rkt"
"infix/parser.rkt"
(planet williams/science/math)
"root-finding.rkt"
"clipboard.rkt")
;;;
;;; NUMERICAL
;;;
(define (nsolve f lower upper)
(define max-iterations 150)
(define eps-rel double-epsilon)
(define eps-abs double-epsilon)
(define safe-f (λ (x) (if (inexact? x) (f x) (f (->inexact x)))))
(with-handlers ([exn:fail? (λ (e) (user-error (exn-message e)))]
[(λ (x) #t) (λ (e) (user-error "internal error: nsolve"))])
(find-root brent-solver safe-f (->inexact lower) (->inexact upper) eps-abs eps-rel 150)))
(define (->inexact x)
(if (exact? x) (exact->inexact x) x))
;;;
;;;
;;;
(define all-math-texts '())
(define all-renderers '())
(define-syntax (add-renderer! stx)
(syntax-case stx ()
[(_ expr) #'(set! all-renderers (append all-renderers (list expr)))]))
;;;
;;; PLOTTING
;;;
(define x-min (make-parameter -10.0))
(define x-max (make-parameter +10.0))
(define y-min (make-parameter -10.0))
(define y-max (make-parameter +10.0))
(define x-label (make-parameter #f))
(define y-label (make-parameter #f))
(define plot-color (make-parameter 0))
(define (next-plot-color) (plot-color (add1 (plot-color))))
(define (plot-function
f [x-min #f] [x-max #f] [y-min #f] [y-max #f]
[color (begin (next-plot-color) (plot-color))]
[width (line-width)]
[style (line-style)] [alpha (line-alpha)]
[label #f] [samples (line-samples)])
(define (ensure-number-function f)
(lambda (x)
(let ([v (f x)])
(if (number? v) v 0))))
(add-renderer! (function (ensure-number-function f) x-min x-max
#:y-min y-min #:y-max y-max
#:samples samples #:color color
#:width width #:style style
#:alpha alpha #:label label)))
#;(function f
[ x-min
x-max
#:y-min y-min
#:y-max y-max
#:samples samples
#:color color
#:width width
#:style style
#:alpha alpha
#:label label])
#;(lines vs
[ #:x-min x-min
#:x-max x-max
#:y-min y-min
#:y-max y-max
#:color color
#:width width
#:style style
#:alpha alpha
#:label label])
; given points in ps, draws points and connect them with line segments
(define (plot-lines
ps [x-min #f] [x-max #f] [y-min #f] [y-max #f]
[color (line-color)] [width (line-width)]
[style (line-style)] [alpha (line-alpha)]
[label #f])
(let ([vs (map (λ (p) (vector (first p) (second p))) ps)])
(add-renderer! (lines vs
#:x-min x-min #:x-max x-max
#:y-min y-min #:y-max y-max
#:color color
#:width width #:style style
#:alpha alpha #:label label))))
(define (plot-vertical-line x0
[color (line-color)] [width (line-width)]
[style (line-style)] [alpha (line-alpha)]
[label #f])
(plot-lines (list (list x0 (y-min)) (list x0 (y-max)))
(x-min) (x-max) (y-min) (y-max)
color width style alpha label))
(define (plot-horizontal-line y0
[color (line-color)] [width (line-width)]
[style (line-style)] [alpha (line-alpha)]
[label #f])
(plot-lines (list (list (x-min) y0) (list (x-max) y0))
(x-min) (x-max) (y-min) (y-max)
color width style alpha label))
(define (plot-equation f1 f2 solutions
[x-min #f] [x-max #f] [y-min #f] [y-max #f]
[color1 (line-color)] [color2 (add1 (line-color))] [width (line-width)]
[style (line-style)] [alpha (line-alpha)]
[label #f] [samples (line-samples)])
(plot-function f1 x-min x-max y-min y-max color1 width style alpha label samples)
(plot-function f2 x-min x-max y-min y-max color2 width style alpha label samples)
(for ([x0 (in-list solutions)])
(let ([y0 (f1 x0)])
(plot-arrow (list x0 y0) (list x0 0) #:color "black"))))
(define (plot-arrow p1 p2 #:color [color (line-color)])
; Note: Arrow size depends on distance from p1 p2
; Introduce fixed size?
(match-define (list x1 y1) p1)
(match-define (list x2 y2) p2)
(define dx (- x2 x1))
(define dy (- y2 y1))
(define angle (if (and (zero? dy) (zero? dx)) 0 (atan dy dx)))
(define dist (sqrt (+ (sqr dx) (sqr dy))))
(define head-r (* 2/5 dist))
(define head-angle (* 1/6 pi))
(define dx1 (* (cos (+ angle head-angle)) head-r))
(define dy1 (* (sin (+ angle head-angle)) head-r))
(define dx2 (* (cos (- angle head-angle)) head-r))
(define dy2 (* (sin (- angle head-angle)) head-r))
(parameterize ([line-color color])
(plot-lines (list (list x1 y1) (list x2 y2)))
(plot-lines (list (list x2 y2) (list (- x2 dx1) (- y2 dy1))))
(plot-lines (list (list x2 y2) (list (- x2 dx2) (- y2 dy2))))))
(define-syntax (plot stx)
(syntax-case stx ()
[(_ expr)
#'(plot-function expr) ]
[(_ expr id)
#'(plot-function (λ (id) expr))]
[(_ expr id from to)
#'(plot-function (λ (id) expr) from to)]
; TODO: signal error
))
(define (plot-point-label x y [label #f] [color "black"] [size 10])
(add-renderer! (point-label (vector x y) label #:color color #:size size)))
(define (plot-function-label f x [label #f] [color "black"] [size 10])
(add-renderer! (function-label f x label #:color color #:size size)))
#;(function-label
f x
[label
#:color color
#:size size
#:family family
#:anchor anchor
#:angle angle
#:point-color point-color
#:point-fill-color point-fill-color
#:point-size point-size
#:point-line-width point-line-width
#:point-sym point-sym
#:alpha alpha])
(define (points ps)
(define (to-vector p)
(cond [(and (list? p) (= (length p) 2))
(apply vector p)]
[else (error 'points "list of length 2 expected, got ~a" p)]))
(set! all-renderers (cons (plot:points (map to-vector ps)) all-renderers))
"done")
(define math-text%
(class* text% ()
(inherit get-text
get-start-position
select-all
delete
insert
set-position
change-style)
(super-new)
(set! all-math-texts (append all-math-texts (list this)))
; Activation/Deactivation of evaluation of the math box
(define is-active? #t) ; #t will
(define/public (active?) is-active?)
(define/public (activate) (set! is-active? #t))
(define/public (deactivate) (set! is-active? #f))
(define/override (copy-self)
(let ([ed (new math-text%)])
(send ed insert (get-text))
ed))
(define/public (evaluate)
(let* ([expr (remove-old-evaluation-result (get-text))]
[val (if is-active? (evaluate-expr expr) #f)]
[pos (get-start-position)])
(if val
(begin
; normal evaluation
(select-all)
(delete)
(insert expr)
(change-style red-delta)
(insert " => ")
(insert val)
(when pos
(set-position pos))
(send plot-canvas refresh))
(begin
; error in expression
(select-all)
(delete)
(insert expr)))))))
(define (new-math-snip)
(let* ([editor (new math-text%)]
[math-snip (new math-editor-snip% [editor editor])]
[keymap (send editor get-keymap)])
(send editor set-max-undo-history 1024)
; (send math-snip set-style (send text-editor get-style))
(send editor change-style (let ([ (new style-delta%)]) (send set-delta 'change-size 20) ))
(install-math-snip-keymap math-snip)
math-snip))
(define math-editor-snip%
(class* (editor-snip:decorated-mixin editor-snip%) ()
(inherit get-editor border-visible?
get-margin get-inset
get-min-width get-max-width
get-min-height get-max-height)
(super-new)
(define/override (copy)
(let* ([math-snip (new math-editor-snip%)]
[editor (send (get-editor) copy-self)])
(send math-snip set-editor editor)
(send editor set-max-undo-history 1024)
(install-math-snip-keymap math-snip)
math-snip))
(define math-box-menu (new popup-menu% [title "Popupmenu"]))
(define mi (new menu-item% [label "Deactivate"] [parent math-box-menu]
[callback (λ (r e)
(let ([ed (send this get-editor)])
(if (send ed active?)
(begin
(send ed deactivate)
(send ed evaluate) ; In order to remove old evaluation result
(send mi set-label "Activate"))
(begin
(send ed activate)
(send mi set-label "Deactivate")))))]))
(define/override (on-event dc x y editorx editory ev)
(if (eq? (send ev get-event-type) 'right-up)
(send (send this get-admin) popup-menu math-box-menu this
(- (send ev get-x) editorx) (- (send ev get-y) editory))
(super on-event dc x y editorx editory ev)))
(define/override (get-corner-bitmap)
(let ([bitmap (make-object bitmap% 15 15)])
(send (new bitmap-dc% [bitmap bitmap]) draw-text "$" 0 0)
bitmap))
(define/override (get-position)
'left-top)
))
(define my-text%
(class* text% ()
(inherit)
(super-new)))
(define show-x-axis #t)
(define show-y-axis #t)
(define show-grid #f)
(define-syntax (toggle! stx)
(syntax-case stx () [(_ id) #'(set! id (not id))]))
(define plot-canvas-menu (new popup-menu% [title "Popupmenu"]))
(new menu-item% [label "Delete all plots"] [parent plot-canvas-menu]
[callback (λ (r e) (set! all-renderers '()) (send plot-canvas refresh))])
(define show-hide-menu (new menu% [label "Show/hide"] [parent plot-canvas-menu]))
(new menu-item% [label "x-axis"] [parent show-hide-menu]
[callback (λ (r e) (toggle! show-x-axis) (send plot-canvas refresh))])
(new menu-item% [label "y-axis"] [parent show-hide-menu]
[callback (λ (r e) (toggle! show-y-axis) (send plot-canvas refresh))])
(new menu-item% [label "grid"] [parent show-hide-menu]
[callback (λ (r e) (toggle! show-grid) (send plot-canvas refresh))])
(new menu-item% [label "Copy as image"] [parent plot-canvas-menu]
[callback
(λ (r e)
(set-clipboard-bitmap
(let* ([bm (send plot-canvas make-bitmap (send plot-canvas get-width) (send plot-canvas get-height))]
[dc (new bitmap-dc% [bitmap bm])])
(draw-plot dc)
bm))
; TODO: Use this when set-clipboard-bitmap is implemented in the racket gui
#;(send the-clipboard set-clipboard-bitmap
(let* ([bm (send plot-canvas make-bitmap (send plot-canvas get-width) (send plot-canvas get-height))]
[dc (new bitmap-dc% [bitmap bm])])
(draw-plot dc)
bm)))])
(define plot-canvas%
(class* canvas% ()
(super-new)
(define/override (on-event ev)
(if (eq? (send ev get-event-type) 'right-up)
(send plot-canvas popup-menu plot-canvas-menu
(send ev get-x)
(send ev get-y))
(super on-event ev)))))
;;;
;;;
;;;
(define frame (new frame% [label "Racket CAS"] [width 400] [height 400]))
(define vertical-panel (new vertical-panel% [parent frame] [stretchable-height #f]))
(define evaluate-all-button (new button% [parent vertical-panel] [label "Evaluate All"]
[callback
(λ (r e)
(set! all-renderers '())
(send plot-canvas refresh)
(for-each (λ (m) (send m evaluate)) all-math-texts)
(send plot-canvas refresh))]))
(define horizontal-panel (new panel:horizontal-dragable% [parent frame]))
(define canvas (new editor-canvas% [parent horizontal-panel] [min-width 200] [min-height 200] [vert-margin 10] [horiz-margin 10]))
(define text-editor (new my-text% ))
(send text-editor set-max-undo-history 1024)
(send canvas set-editor text-editor)
(send text-editor set-styles-sticky #t)
(send text-editor change-style (let ([ (new style-delta%)]) (send set-delta 'change-size 20) ))
(send text-editor set-caret-owner #f 'global)
(define (list-if p . more)
(if p more '()))
(define (draw-plot dc)
(let ()
(send dc suspend-flush)
(plot/dc (append (list-if show-x-axis (x-axis) )
(list-if show-y-axis (y-axis) )
(list-if show-grid (x-tick-lines) (y-tick-lines))
all-renderers)
dc
0 0
(send plot-canvas get-width)
(send plot-canvas get-height)
#:x-min (x-min)
#:x-max (x-max)
#:x-label (x-label)
#:y-min (y-min)
#:y-max (x-max)
#:y-label (y-label)
#:title #f)
(send dc resume-flush)))
(define plot-canvas
(new plot-canvas% [parent horizontal-panel]
[min-width 200] [min-height 200] [vert-margin 10] [horiz-margin 10]
[paint-callback (λ (c dc) (draw-plot dc))]))
(define status-panel (new horizontal-panel% [parent frame] [stretchable-height #f] [alignment '(left center)]))
(define status-message (new message% [parent status-panel] [label "Status:"] [auto-resize #t]))
(define menu-bar (new menu-bar% [parent frame]))
(define menu-edit (new menu% [label "Edit"] [parent menu-bar]))
(define menu-font (new menu% [label "Font"] [parent menu-bar]))
(append-editor-operation-menu-items menu-edit #f)
(append-editor-font-menu-items menu-font)
(application:current-app-name "Racket CAS") ; Appears in help menu
(define (make-color-delta color)
(send (make-object style-delta%) set-delta-foreground color))
(define red-delta (make-color-delta (make-object color% "red")))
(define blue-delta (make-color-delta (make-object color% "blue")))
(define (remove-old-evaluation-result str)
(let ([m (regexp-match #rx"(.*) =>.*" str)])
(if m (second m) str)))
(define (evaluate-expr str)
(with-handlers
([(λ (e) #t)
(λ (e) (begin
(display e) (newline)
(send status-message set-label
(format "eval: invalid expression, got ~a" str))
#f))])
(format "~a"
(eval-syntax
(parse-expression
(datum->syntax #'here str
(list 'src-name 1 0 1 (string-length str)))
(open-input-string str))))))
(define (install-math-snip-keymap math-snip)
(let ([keymap (send (send math-snip get-editor) get-keymap)])
(define (register name char shortcuts)
(let ([insert-name (string-append "insert-" name)])
(send keymap add-function insert-name
(λ (ed e) (send ed insert char)))
(for ([shortcut shortcuts])
(send keymap map-function shortcut insert-name))))
(send keymap add-function "evaluate-math"
(λ (ed e) (send ed evaluate)))
(send keymap add-function "left-willing-to-leave"
(λ (ed e)
(let ([pos (send ed get-start-position)])
(if (= pos 0)
(begin
(send text-editor set-caret-owner #f)
(send text-editor set-position
(send text-editor get-snip-position math-snip)))
(send ed move-position 'left)))))
(send keymap add-function "right-willing-to-leave"
(λ (ed e)
(let ([pos (send ed get-start-position)])
(if (= pos (send ed last-position))
(begin
(send text-editor set-caret-owner #f)
(send text-editor set-position
(+ 1 (send text-editor get-snip-position math-snip))))
(send ed move-position 'right)))))
(send keymap add-function "newline"
(λ (ed e) (send ed insert #\newline)))
(register "lambda" #\λ '("d:\\" "c:\\"))
(register "Lambda" #\Λ '("c:L"))
(register "alpha" #\α '("c:a"))
(register "beta" #\β '("c:b"))
(register "gamma" #\γ '("c:g"))
(register "delta" #\δ '("c:d"))
(register "epsilon" #\ε '("c:e"))
(register "rho" #\ρ '("c:r"))
(register "Gamma" #\Γ '("c:G"))
(register "Delta" #\∆ '("c:D"))
(send keymap map-function "s:enter" "newline")
(send keymap map-function "enter" "evaluate-math")
(send keymap map-function "~s:left" "left-willing-to-leave")
(send keymap map-function "~s:right" "right-willing-to-leave")))
;;;
;;; KEYBINDINGS FOR THE DOCUMENT EDITOR
;;;
(define keymap (send text-editor get-keymap))
;(add-editor-keymap-functions keymap)
;(add-text-keymap-functions keymap)
(send keymap add-function "insert-math"
(λ (in e)
; get the current selection, if any,
(let ([start (box #f)] [end (box #f)])
(send in get-position start end)
(let ([selected-text
(if (and (unbox start) (unbox end))
(send in get-text (unbox start) (unbox end))
#f)]
; make a new math-snip, and insert the selected text
[math-snip (new-math-snip)])
(send text-editor insert math-snip)
(send text-editor set-caret-owner math-snip 'display)
(when selected-text
(send (send math-snip get-editor) insert selected-text))))))
(send keymap add-function "left-willing-to-enter-math-snip"
(λ (in e)
; left: if the position before the caret is a math-editor, enter it
(let* ([pos (send in get-start-position)]
[snip-pos (box #f)]
[snip (send in find-snip pos 'before-or-none snip-pos)])
(if (and snip (is-a? snip math-editor-snip%))
(begin
(send in set-caret-owner snip)
(let ([ed (send snip get-editor)])
(send ed set-position (send ed last-position))))
(send in move-position 'left)))))
(send keymap add-function "right-willing-to-enter-math-snip"
(λ (in e)
; right: if the position after the caret is a math-editor, enter it
(let* ([pos (send in get-start-position)]
[snip-pos (box #f)]
[snip (send in find-snip pos 'after-or-none snip-pos)])
(if (and snip
(is-a? snip editor-snip%)
(is-a? (send snip get-editor) math-text%))
(begin
(send in set-caret-owner snip)
(let ([ed (send snip get-editor)])
(send ed set-position 0)))
(send in move-position 'right)))))
(send keymap add-function "bold"
(λ (in e)
; TODO: twice => toggle
(send text-editor change-style
(make-object style-delta% 'change-weight 'bold))))
(send keymap add-function "italic"
(λ (in e)
; TODO: twice => toggle
(send text-editor change-style
(make-object style-delta% 'change-style 'italic))))
(send keymap map-function "c:m" "insert-math")
(send keymap map-function "d:m" "insert-math") ; OS X cmd
(send keymap map-function "~s:left" "left-willing-to-enter-math-snip")
(send keymap map-function "~s:right" "right-willing-to-enter-math-snip")
(send keymap map-function "c:b" "bold") ; Win ctrl
(send keymap map-function "d:b" "bold") ; OS X cmd
(send keymap map-function "c:i" "italic") ; Win ctrl
(send keymap map-function "d:i" "italic") ; OS X cmd
;;;
;;; ERRORS AND WARNINGS
;;;
(define (user-error text)
(let ([msg (format "ERROR: ~a" text)])
(send status-message set-label msg)
msg))
(define (user-warning text)
(let ([msg (format "WARNING: ~a" text)])
(send status-message set-label msg)
msg))
;;;
;;; BIG BANG
;;;
; (send frame create-status-line)
; (send frame set-status-text "Ready")
(send frame maximize #t)
(send frame show #t)
; (graphical-read-eval-print-loop)

BIN
infix/.DS_Store vendored Normal file

Binary file not shown.

11
infix/info.ss Normal file
View File

@ -0,0 +1,11 @@
#lang setup/infotab
(define name "Infix Expressions")
(define blurb
(list "Infix expressions: Write mathematical expressions with standard syntax."))
(define scribblings '(["scribblings/manual.scrbl"]))
(define categories '(devtools))
(define version "1.0")
(define primary-file "main.ss")
(define compile-omit-paths '("tests"))
(define release-notes (list))
(define repositories '("4.x"))

81
infix/main.rkt Normal file
View File

@ -0,0 +1,81 @@
#lang at-exp scheme
(provide $ $quote $quote-syntax #%infix)
(require "parameter.ss"
scheme/port
scheme/stxparam
(for-syntax scheme)
;(planet soegaard/infix/parser)
;(for-syntax (planet soegaard/infix/parser))
"parser.rkt"
(for-syntax "parser.rkt"))
(define-syntax ($quote stx)
(syntax-case stx ()
[(_ item ...)
(with-syntax ([(q ...) (local-expand #'($ item ...) 'expression #f)])
#''(#%infix (q ...)))]))
(define-syntax ($quote-syntax stx)
(syntax-case stx ()
[(_ item ...)
(with-syntax ([(q ...) (local-expand #'($ item ...) 'expression #f)])
#'#'(#%infix (q ...)))]))
(define-syntax ($ stx)
(syntax-case stx ()
[(_ item ...)
(let* ([from-at? (syntax-property stx 'scribble)])
(if from-at?
; reintroduce the original (discarded) indentation
(with-syntax
([(item ...)
(let loop ([items (syntax->list #'(item ...))])
(if (null? items)
'()
(let* ([fst (car items)]
[prop (syntax-property fst 'scribble)]
[rst (loop (cdr items))])
(cond [(eq? prop 'indentation) rst]
[(not (and (pair? prop)
(eq? (car prop) 'newline)))
(cons fst rst)]
[else (cons (datum->syntax fst (cadr prop) fst)
rst)]))))])
#'($$ item ...))
#'($$ item ...)))]))
(define-syntax ($$ stx)
(syntax-case stx ()
[(_ str str* ...)
(let* ([from-at? (syntax-property stx 'scribble)]
[offset (if from-at? 0 1)]
[ip (open-input-string
(apply string-append
(map syntax->datum
(syntax->list #'(str str* ...)))))])
;(display "from-at?: ") (display from-at?) (newline)
;(display "str: ") (display #'str) (newline)
;(display "str*: ") (display #'(str* ...)) (newline)
;(display "stx: ") (display stx) (newline)
(port-count-lines! ip)
(let* ([line (syntax-line #'str)]
[col (+ (syntax-column #'str) offset)]
[pos (+ (syntax-position #'str) offset -1)])
;(display (list line col pos)) (newline)
(let ([result
(parse-expression
(if from-at?
(datum->syntax
#'str
(apply string-append
(map syntax->datum
(syntax->list #'(str str* ...))))
(list (syntax-source #'str)
line col pos
(syntax-span #'str)))
#'str)
ip)])
;(display "result: ") (display result) (newline)
result)))]))

8
infix/parameter.ss Normal file
View File

@ -0,0 +1,8 @@
#lang scheme
(provide #%infix)
(require scheme/stxparam)
(define-syntax-parameter #%infix
(λ (stx)
(syntax-case stx ()
[(_ expr) #'expr])))

296
infix/parser.rkt Normal file
View File

@ -0,0 +1,296 @@
#lang scheme
(require "parameter.ss")
;;;
;;; NOTES:
;;; Changes from planet version: ]] (CDB) Bug fixed
;;; Strings are supported.
;;; Assignments changed from set! to define.
;;; Assignment of functions.
;;; Bug fix: identifiers with more than one _ wasn't converted correctly
; <e> = <num>
; | <id> variable reference
; | <e> [ <args> ] application
; | { <args> } list construction
; | <e> + <e> addition
; | <e> - <e> subtraction
; | <e> * <e> multiplication
; | <e> / <e> division
; | <e> ^ <e> exponentiation
; | - <e> negation
; | ( <e> ) grouping
; <id> An identifier begins with a letter,
; and is optionally followed by series of letters, digits or underscores.
; An underscore is converted to a -. Thus list_ref will refer to list-ref.
; <num> A number is an non-empty series of digits,
; optionally followed by a period followed by a series of digits.
; <string> A number is a " followed by a series of non-" characters followed by a " .
(provide parse-expression parse-expression-from-port parse-math-string)
(require parser-tools/yacc
parser-tools/lex
(prefix-in : parser-tools/lex-sre)
syntax/readerr)
(define-tokens value-tokens (NUMBER IDENTIFIER STRING))
(define-empty-tokens op-tokens (newline :=
OP CP ; ( )
OB CB ; [ ]
OC CC ; { }
ODB ; [[ ]]
COMMA ; ,
SEMI ; ;
PERIOD ; .
LAMBDA ; lambda or λ
SQRT ; √
NEG ; ¬ (logical negation)
LESS-EQUAL ; <= or ≤
GREATER-EQUAL ; >= or ≥
NOT-EQUAL ; <> or ≠
= < >
+ - * / ^
EOF))
(define-lex-abbrevs
[letter (:or (:/ "a" "z") (:/ #\A #\Z) )]
[digit (:/ #\0 #\9)]
[string (:: #\" (:* (:or letter digit #\_ #\?)) #\")]
[identifier (:: letter (:* (:or letter digit #\_ #\?)))])
(define expression-lexer
(lexer-src-pos
[(eof) 'EOF]
[(:or #\tab #\space #\newline) ; this skips whitespace
(return-without-pos (expression-lexer input-port))]
[#\newline (token-newline)] ; (token-newline) returns 'newline
[(:or ":=" "+" "-" "*" "/" "^" "<" ">" "=" "\"") (string->symbol lexeme)]
["(" 'OP]
[")" 'CP]
["[" 'OB]
["]" 'CB]
["{" 'OC]
["}" 'CC]
["[[" 'ODB]
; ["]]" 'CDB]
["," 'COMMA]
[";" 'SEMI]
["." 'PERIOD]
[#\λ 'LAMBDA]
["lambda" 'LAMBDA]
["" 'SQRT]
["¬" 'NEG]
["" 'LESS-EQUAL]
["<=" 'LESS-EQUAL]
["" 'GREATER-EQUAL]
[">=" 'GREATER-EQUAL]
["<>" 'NOT-EQUAL]
["" 'NOT-EQUAL]
[string
(token-STRING (substring lexeme 1 (- (string-length lexeme) 1)))]
[identifier
(token-IDENTIFIER (string->symbol (regexp-replace* #rx"_" lexeme "-")))]
[(:+ digit) (token-NUMBER (string->number lexeme))]
[(:: (:+ digit) #\. (:* digit)) (token-NUMBER (string->number lexeme))]))
;; A macro to build the syntax object
(define-syntax (b stx)
(syntax-case stx ()
((_ o value start end)
(with-syntax
((start-pos (datum->syntax #'start
(string->symbol
(format "$~a-start-pos"
(syntax->datum #'start)))))
(end-pos (datum->syntax #'end
(string->symbol
(format "$~a-end-pos"
(syntax->datum #'end))))))
#`(datum->syntax o
value
(list (if (syntax? o) (syntax-source o) 'missing-in-action--sorry)
(if o (+ (syntax-line o) (position-line start-pos) -1) #f)
(if o (+ (syntax-column o) (position-offset start-pos) ) #f)
(if o (+ (syntax-position o) (position-offset start-pos)) #f)
(- (position-offset end-pos)
(position-offset start-pos)))
o o)))))
; for testing: builds lists instead of syntax objects
#;(define-syntax (b stx)
(syntax-case stx ()
[(_ _ val _ _)
#'val]))
(define (display-position-token pos)
(display (list (position-offset pos)
(position-line pos)
(position-col pos))))
(define (expression-parser source-name orig-stx)
(define o orig-stx)
(parser
(src-pos)
(suppress) ; hmm...
(start start)
(end newline EOF)
(tokens value-tokens op-tokens)
(error (lambda (token-ok? name val start end)
; The first argument will be #f if and only if the error is that an invalid token was received.
; The second and third arguments will be the name and the value of the token at which the error was detected.
; The fourth and fifth arguments, if present, provide the source positions of that token.
(unless #f #; (string? (syntax->datum o))
(display "DEBUG: ")
(display (list o token-ok? name val start end))
(display-position-token start) (newline)
(display-position-token end) (newline)
(newline))
(raise-syntax-error
'expression-parser "parse error" o
(datum->syntax
o
(if (string? (syntax->datum o))
(substring (syntax->datum o)
(max 0 (- (position-offset start) 1))
(min (- (position-offset end) 1)
(string-length (syntax->datum o))))
(begin
(display o)
(newline)
"fooooooooo"))
(list (if (syntax? o) (syntax-source o) 'missing-in-action--sorry)
(if o (+ (syntax-line o) (position-line start) -1) #f)
(if o (+ (syntax-column o) (position-offset start)) #f)
(if o (+ (syntax-position o) (position-offset start)) #f)
(- (position-offset end)
(position-offset start)))))))
(precs (right :=)
(left - +)
(left * /)
(right OB)
(right ^)
(left =) ; comparisons
(right NEG)
(left SEMI))
(grammar
(start [(exp) (b o `(#%infix ,$1) 1 1)]
[() #f])
;; If there is an error, ignore everything before the error
;; and try to start over right after the error
(args [(exp) (b o (list $1) 1 1)]
[(exp COMMA args) (b o (cons $1 $3) 1 3)]
[() '()])
(ids [() '()]
[(IDENTIFIER ids) (b o (cons $1 $2) 1 2)])
(parenthensis-exp
[(OP exp CP) $2])
(atom
[(NUMBER) (b o $1 1 1)]
[(IDENTIFIER) (b o $1 1 1)]
[(STRING) (b o $1 1 1)]
[(parenthensis-exp) $1])
(construction-exp
[(OC args CC) (b o `(,(b o 'list 1 3) ,@$2) 1 3)]
[(OP LAMBDA ids PERIOD exp CP) (b o `(,(b o 'lambda 2 2) ,$3 ,$5) 1 6)]
[(atom) $1])
(application-exp
[(application-exp OB args CB) (b o `(,$1 ,@$3) 1 4)] ; function application
[(application-exp ODB exp CB CB) (b o `(,(b o 'list-ref 1 4) ,$1 ,$3) 1 4)] ; list ref
[(construction-exp) $1])
#;(implicit-exp
[(application-exp application-exp) (prec *) (b o `(,(b o '* 1 2) ,$1 ,$2) 1 2)] ; implicit
[(application-exp) $1])
(power-exp
[(application-exp ^ power-exp) (prec ^) (b o `(expt ,$1 ,$3) 1 3)]
[(application-exp) $1])
(sqrt-exp
[(SQRT sqrt-exp) (b o `(,(b o 'sqrt 1 1) ,$2) 1 2)]
[(power-exp) $1])
(negation-exp
[(- negation-exp) (b o `(,(b o '- 1 1) ,$2) 1 2)]
[(sqrt-exp) $1])
(multiplication-exp
[(multiplication-exp * negation-exp) (prec *) (b o `(,(b o '* 2 2) ,$1 ,$3) 1 3)]
[(multiplication-exp / negation-exp) (prec /) (b o `(,(b o '/ 2 2) ,$1 ,$3) 1 3)]
;[(multiplication-exp negation-exp) (prec *) (b o `(,(b o '* 1 2) ,$1 ,$2) 1 2)]
[(negation-exp) $1])
(addition-exp
[(addition-exp - multiplication-exp) (prec -) (b o `(,(b o '- 2 2) ,$1 ,$3) 1 3)]
[(addition-exp + multiplication-exp) (prec +) (b o `(,(b o '+ 2 2) ,$1 ,$3) 1 3)]
[(multiplication-exp) $1])
(order-exp
[(addition-exp LESS-EQUAL addition-exp) (prec =) (b o `(,(b o '<= 2 2) ,$1 ,$3) 1 3)]
[(addition-exp < addition-exp) (prec =) (b o `(,(b o '< 2 2) ,$1 ,$3) 1 3)]
[(addition-exp GREATER-EQUAL addition-exp) (prec =) (b o `(,(b o '>= 2 2) ,$1 ,$3) 1 3)]
[(addition-exp > addition-exp) (prec =) (b o `(,(b o '> 2 2) ,$1 ,$3) 1 3)]
[(addition-exp NOT-EQUAL addition-exp) (prec =) (b o `(not (,(b o '= 2 2) ,$1 ,$3)) 1 3)]
[(addition-exp = addition-exp) (prec =) (b o `(,(b o '= 2 2) ,$1 ,$3) 1 3)]
[(addition-exp) $1])
(logical-negation-exp
[(NEG logical-negation-exp) (prec NEG) (b o `(,(b o 'not 1 1) ,$2) 1 2)]
[(order-exp) $1])
(assignment-exp
[(IDENTIFIER := assignment-exp) (b o `(,(b o 'define 2 2) ,$1 ,$3) 1 3)]
[(IDENTIFIER OP IDENTIFIER CP := assignment-exp) (b o `(,(b o 'define 3 3) (,$1 ,$3) ,$6) 1 6)]
[(logical-negation-exp) $1])
(compound-exp
[(compound-exp SEMI assignment-exp) (b o `(,(b o 'begin 2 2) ,$1 ,$3) 1 3)]
[(assignment-exp) $1])
(exp
[(compound-exp) $1]))))
;; run the calculator on the given input-port
(define (parse-expression-from-port ip)
(port-count-lines! ip)
(letrec ((one-line
(lambda ()
(let ((result ((expression-parser "test" #f)
(λ () (expression-lexer ip)))))
(when result
(printf "~a~n" result)
(one-line))))))
(one-line)))
(define (parse-expression stx ip)
(port-count-lines! ip)
((expression-parser stx stx) (λ () (expression-lexer ip))))
(define parse-math-string
(case-lambda
[(s)
(display (format "~a\n" s))
(parse-math-string s (let ([here #'here]) (datum->syntax here s here)))]
[(s src)
(cond
[(string? s)
(parse-expression src (open-input-string s))]
[(special-comment? s)
s]
[else
(if (or (symbol? s) (boolean? s))
s
(datum->syntax (second s) (cons 'quote-syntax (cdr s))))])]))

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,166 @@
/* See the beginning of "scribble.css". */
/* Monospace: */
.ScmIn, .ScmRdr, .ScmPn, .ScmMeta,
.ScmMod, .ScmKw, .ScmVar, .ScmSym,
.ScmRes, .ScmOut, .ScmCmt, .ScmVal {
font-family: monospace;
}
/* Serif: */
.inheritedlbl {
font-family: serif;
}
/* ---------------------------------------- */
/* Inherited methods, left margin */
.inherited {
width: 100%;
margin-top: 0.5em;
text-align: left;
background-color: #ECF5F5;
}
.inherited td {
font-size: 82%;
padding-left: 1em;
text-indent: -0.8em;
padding-right: 0.2em;
}
.inheritedlbl {
font-style: italic;
}
/* ---------------------------------------- */
/* Scheme text styles */
.ScmIn {
color: #cc6633;
background-color: #eeeeee;
}
.ScmInBG {
background-color: #eeeeee;
}
.ScmRdr {
}
.ScmPn {
color: #843c24;
}
.ScmMeta {
color: #262680;
}
.ScmMod {
color: black;
}
.ScmOpt {
color: black;
}
.ScmKw {
color: black;
font-weight: bold;
}
.ScmErr {
color: red;
font-style: italic;
}
.ScmVar {
color: #262680;
font-style: italic;
}
.ScmSym {
color: #262680;
}
.ScmValLink {
text-decoration: none;
color: blue;
}
.ScmModLink {
text-decoration: none;
color: blue;
}
.ScmStxLink {
text-decoration: none;
color: black;
font-weight: bold;
}
.ScmRes {
color: #0000af;
}
.ScmOut {
color: #960096;
}
.ScmCmt {
color: #c2741f;
}
.ScmVal {
color: #228b22;
}
/* ---------------------------------------- */
/* Some inline styles */
.together {
width: 100%;
}
.prototype td {
vertical-align: text-top;
}
.longprototype td {
vertical-align: bottom;
}
.ScmBlk td {
vertical-align: baseline;
}
.argcontract td {
vertical-align: text-top;
}
.highlighted {
background-color: #ddddff;
}
.defmodule {
width: 100%;
background-color: #F5F5DC;
}
.specgrammar {
float: right;
}
.SBibliography td {
vertical-align: text-top;
}
.leftindent {
margin-left: 1em;
margin-right: 0em;
}
.insetpara {
margin-left: 1em;
margin-right: 1em;
}

View File

@ -0,0 +1,67 @@
// Common functionality for PLT documentation pages
function GetCookie(key, def) {
if (document.cookie.length <= 0) return def;
var i, cookiestrs = document.cookie.split(/; */);
for (i = 0; i < cookiestrs.length; i++) {
var cur = cookiestrs[i];
var eql = cur.indexOf('=');
if (eql >= 0 && cur.substring(0,eql) == key)
return unescape(cur.substring(eql+1));
}
return def;
}
function SetCookie(key, val) {
var d = new Date();
d.setTime(d.getTime()+(365*24*60*60*1000));
document.cookie =
key + "=" + escape(val) + "; expires="+ d.toGMTString() + "; path=/";
}
// note that this always stores a directory name, ending with a "/"
function SetPLTRoot(ver, relative) {
var root = location.protocol + "//" + location.host
+ NormalizePath(location.pathname.replace(/[^\/]*$/, relative));
SetCookie("PLT_Root."+ver, root);
}
// adding index.html works because of the above
function GotoPLTRoot(ver, relative) {
var u = GetCookie("PLT_Root."+ver, null);
if (u == null) return true; // no cookie: use plain up link
// the relative path is optional, default goes to the toplevel start page
if (!relative) relative = "index.html";
location = u + relative;
return false;
}
normalize_rxs = [/\/\/+/g, /\/\.(\/|$)/, /\/[^\/]*\/\.\.(\/|$)/];
function NormalizePath(path) {
var tmp, i;
for (i = 0; i < normalize_rxs.length; i++)
while ((tmp = path.replace(normalize_rxs[i], "/")) != path) path = tmp;
return path;
}
function DoSearchKey(event, field, ver, top_path) {
var val = field.value;
if (event && event.keyCode == 13) {
var u = GetCookie("PLT_Root."+ver, null);
if (u == null) u = top_path; // default: go to the top path
location = u + "search/index.html" + "?q=" + escape(val);
return false;
}
return true;
}
function TocviewToggle(glyph,id) {
var s = document.getElementById(id).style;
var expand = s.display == "none";
s.display = expand ? "block" : "none";
glyph.innerHTML = expand ? "&#9660;" : "&#9658;";
}
// `noscript' is problematic in some browsers (always renders as a
// block), use this hack instead (does not always work!)
// document.write("<style>mynoscript { display:none; }</style>");

View File

@ -0,0 +1,413 @@
/* CSS seems backward: List all the classes for which we want a
particular font, so that the font can be changed in one place. (It
would be nicer to reference a font definition from all the places
that we want it.)
As you read the rest of the file, remember to double-check here to
see if any font is set. */
/* Monospace: */
.maincolumn, .refpara, .tocset, .stt, .hspace {
font-family: monospace;
}
/* Serif: */
.main, .refcontent, .tocview, .tocsub, i {
font-family: serif;
}
/* Sans-serif: */
.version, .versionNoNav {
font-family: sans-serif;
}
/* ---------------------------------------- */
p, .SIntrapara {
display: block;
margin: 1em 0;
}
h2 { /* per-page main title */
margin-top: 0;
}
h3, h4, h5, h6, h7, h8 {
margin-top: 1.75em;
margin-bottom: 0.5em;
}
/* Needed for browsers like Opera, and eventually for HTML 4 conformance.
This means that multiple paragraphs in a table element do not have a space
between them. */
table p {
margin-top: 0;
margin-bottom: 0;
}
/* ---------------------------------------- */
/* Main */
body {
color: black;
background-color: #ffffff;
}
table td {
padding-left: 0;
padding-right: 0;
}
.maincolumn {
width: 43em;
margin-right: -40em;
margin-left: 15em;
}
.main {
text-align: left;
}
/* ---------------------------------------- */
/* Navigation */
.navsettop, .navsetbottom {
background-color: #f0f0e0;
padding: 0.25em 0 0.25em 0;
}
.navsettop {
margin-bottom: 1.5em;
border-bottom: 2px solid #e0e0c0;
}
.navsetbottom {
margin-top: 2em;
border-top: 2px solid #e0e0c0;
}
.navleft {
margin-left: 1ex;
position: relative;
float: left;
white-space: nowrap;
}
.navright {
margin-right: 1ex;
position: relative;
float: right;
white-space: nowrap;
}
.nonavigation {
color: #e0e0e0;
}
.searchform {
display: inline;
margin: 0;
padding: 0;
}
.searchbox {
width: 16em;
margin: 0px;
padding: 0px;
background-color: #eee;
border: 1px solid #ddd;
text-align: center;
vertical-align: middle;
}
/* ---------------------------------------- */
/* Version */
.versionbox {
position: relative;
float: right;
left: 2em;
height: 0em;
width: 13em;
margin: 0em -13em 0em 0em;
}
.version {
font-size: small;
}
.versionNoNav {
font-size: xx-small; /* avoid overlap with author */
}
/* ---------------------------------------- */
/* Margin notes */
.refpara {
position: relative;
float: right;
left: 2em;
top: -1em;
height: 0em;
width: 13em;
margin: 0em -13em 0em 0em;
}
.refcolumn {
background-color: #F5F5DC;
display: block;
position: relative;
width: 13em;
font-size: 85%;
border: 0.5em solid #F5F5DC;
margin: 0 0 0 0;
}
.refcontent {
margin: 0 0 0 0;
}
.refcontent p {
margin-top: 0;
margin-bottom: 0;
}
/* ---------------------------------------- */
/* Table of contents, inline */
.toclink {
text-decoration: none;
color: blue;
font-size: 85%;
}
.toptoclink {
text-decoration: none;
color: blue;
font-weight: bold;
}
/* ---------------------------------------- */
/* Table of contents, left margin */
.tocset {
position: relative;
float: left;
width: 12.5em;
margin-right: 2em;
}
.tocset td {
vertical-align: text-top;
}
.tocview {
text-align: left;
background-color: #f0f0e0;
}
.tocsub {
text-align: left;
margin-top: 0.5em;
background-color: #f0f0e0;
}
.tocviewlist, .tocsublist {
margin-left: 0.2em;
margin-right: 0.2em;
padding-top: 0.2em;
padding-bottom: 0.2em;
}
.tocviewlist table {
font-size: 82%;
}
.tocviewsublist, .tocviewsublistonly, .tocviewsublisttop, .tocviewsublistbottom {
margin-left: 0.4em;
border-left: 1px solid #bbf;
padding-left: 0.8em;
}
.tocviewsublist {
margin-bottom: 1em;
}
.tocviewsublist table,
.tocviewsublistonly table,
.tocviewsublisttop table,
.tocviewsublistbottom table {
font-size: 75%;
}
.tocviewtitle * {
font-weight: bold;
}
.tocviewlink {
text-decoration: none;
color: blue;
}
.tocviewselflink {
text-decoration: underline;
color: blue;
}
.tocviewtoggle {
text-decoration: none;
color: blue;
font-size: 75%; /* looks better, and avoids bounce when toggling sub-sections due to font alignments */
}
.tocsublist td {
padding-left: 1em;
text-indent: -1em;
}
.tocsublinknumber {
font-size: 82%;
}
.tocsublink {
font-size: 82%;
text-decoration: none;
}
.tocsubseclink {
font-size: 82%;
text-decoration: none;
}
.tocsubnonseclink {
font-size: 82%;
text-decoration: none;
padding-left: 0.5em;
}
.tocsubtitle {
font-size: 82%;
font-style: italic;
margin: 0.2em;
}
.sepspace {
font-size: 40%;
}
.septitle {
font-size: 70%;
}
/* ---------------------------------------- */
/* Some inline styles */
.indexlink {
text-decoration: none;
}
.nobreak {
white-space: nowrap;
}
.stt {
}
.title {
font-size: 200%;
font-weight: normal;
margin-top: 2.8em;
text-align: center;
}
pre { margin-left: 2em; }
blockquote { margin-left: 2em; }
ol { list-style-type: decimal; }
ol ol { list-style-type: lower-alpha; }
ol ol ol { list-style-type: lower-roman; }
ol ol ol ol { list-style-type: upper-alpha; }
i {
}
.SubFlow {
display: block;
}
.boxed {
width: 100%;
background-color: #E8E8FF;
}
.hspace {
}
.slant {
font-style: oblique;
}
.badlink {
text-decoration: underline;
color: red;
}
.plainlink {
text-decoration: none;
color: blue;
}
.techoutside { text-decoration: underline; color: #b0b0b0; }
.techoutside:hover { text-decoration: underline; color: blue; }
/* .techinside:hover doesn't work with FF, .techinside:hover>
.techinside doesn't work with IE, so use both (and IE doesn't
work with inherit in the second one, so use blue directly) */
.techinside { color: black; }
.techinside:hover { color: blue; }
.techoutside:hover>.techinside { color: inherit; }
.SCentered {
text-align: center;
}
.imageleft {
float: left;
margin-right: 0.3em;
}
.Smaller{
font-size: 82%;
}
.Larger{
font-size: 122%;
}
/* A hack, inserted to break some Scheme ids: */
.mywbr {
width: 0;
font-size: 1px;
}
.compact li p {
margin: 0em;
padding: 0em;
}
.noborder img {
border: 0;
}
.SAuthorListBox {
position: relative;
float: right;
left: 2em;
top: -2.5em;
height: 0em;
width: 13em;
margin: 0em -13em 0em 0em;
}
.SAuthorList {
font-size: 82%;
}
.SAuthorList:before {
content: "by ";
}
.author {
display: inline;
white-space: nowrap;
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,275 @@
#lang scribble/doc
@(require scribble/manual
scribble/eval
scribble/basic
scribble/bnf
(planet cce/scheme:4:1/planet)
(for-label (planet dherman/pprint:4)
scheme/base
scheme/contract
"../main.ss")
"util.ss")
@title[#:tag "top"]{@bold{Infix Expressions} for PLT Scheme}
@author[(author+email "Jens Axel Søgaard" "jensaxel@soegaard.net")]
This package provides infix notation for writing mathematical expressions.
@section{Getting Started}
A simple example, calculating 1+2*3.
@verbatim[#:indent 2]|{
#lang at-exp scheme
(require (planet soegaard/infix))
(display (format "1+2*3 is ~a\n" @${1+2*3} )
}|
@subsection{Arithmetical Operations}
The arithmetical operations +, -, *, / and ^ is written with standard
mathematical notation. Normal parentheseses are used for grouping.
@verbatim[#:indent 2]|{
#lang at-exp scheme
(require (planet soegaard/infix))
@${2*(1+3^4)} ; evaluates to 164
}|
@subsection{Identifiers}
Identifiers refer to the current lexical scope:
@verbatim[#:indent 2]|{
#lang at-exp scheme
(require (planet soegaard/infix))
(define x 41)
@${ x+1 } ; evaluates to 42
}|
@subsection{Application}
Function application use square brackets (as does Mathematica).
Here @scheme[sqrt] is bound to the square root function defined
in the language after at-exp, here the scheme language.
@verbatim[#:indent 2]|{
#lang at-exp scheme
(require (planet soegaard/infix))
(display (format "The square root of 64 is ~a\n" @${sqrt[64]} ))
@${ list[1,2,3] } evaluates to the list (1 2 3)
}|
@subsection{Lists}
Lists are written with curly brackets {}.
@verbatim[#:indent 2]|{
#lang at-exp scheme
(require (planet soegaard/infix))
@${ {1,2,1+2} } ; evaluates to (1 2 3)
}|
@subsection{List Reference}
List reference is written with double square brackets.
@verbatim[#:indent 2]|{
#lang at-exp scheme
(require (planet soegaard/infix))
(define xs '(a b c))
@${ xs[[1]] } ; evaluates to b
}|
@subsection{Anonymous Functions}
The syntax (λ ids . expr) where ids are a space separated list
of identifiers evaluates to function in which the ids are bound in
body expressions.
@verbatim[#:indent 2]|{
#lang at-exp scheme
(require (planet soegaard/infix))
@${ (λ.1)[]} ; evaluates to 1
@${ (λx.x+1)[2]} ; evaluates to 3
@${ (λx y.x+y+1)[1,2]} ; evaluates to 4
}|
@subsection{Square Roots}
Square roots can be written with a literal square root:
@verbatim[#:indent 2]|{
#lang at-exp scheme
(require (planet soegaard/infix))
@${√4} ; evaluates to 2
@${√(2+2)} ; evaluates to 2
}|
@subsection{Comparisons}
The comparison operators <, =, >, <=, and >= are available.
The syntaxes ≤ and ≥ for <= and >= respectively, works too.
Inequality is tested with <>.
@subsection{Logical Negation}
Logical negations is written as ¬.
@verbatim[#:indent 2]|{
#lang at-exp scheme
(require (planet soegaard/infix))
@${ ¬true } ; evaluates to #f
@${ ¬(1<2) } ; evaluates to #f
}|
@subsection{Assignment}
Assignment is written with := .
@subsection{Sequencing}
A series of expresions can be evaluated by interspersing semi colons
between the expressions.
@verbatim[#:indent 2]|{
#lang at-exp scheme
(require (planet soegaard/infix))
(define x 0)
@${ (x:=1); (x+3) } ; evaluates to 4
}|
@section{Examples}
@subsection{Example: Fibonacci}
This problem is from the Euler Project.
Each new term in the Fibonacci sequence is generated by adding the
previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
Find the sum of all the even-valued terms in the sequence which do not
exceed four million.
@verbatim[#:indent 2]|{
#lang at-exp scheme
(require
(planet soegaard/infix)
(only-in (planet "while.scm" ("soegaard" "control.plt" 2 0))
while))
(define-values (f g t) (values 1 2 0))
(define sum f)
@${
while[ g< 4000000,
when[ even?[g], sum:=sum+g];
t := f + g;
f := g;
g := t];
sum}|
@subsection{Example: Difference Between a Sum of Squares and the Square of a Sum}
This problem is from the Euler Project.
The sum of the squares of the first ten natural numbers is,
1^2 + 2^2 + ... + 10^2 = 385
The square of the sum of the first ten natural numbers is,
(1 + 2 + ... + 10)^2 = 552 = 3025
Hence the difference between the sum of the squares of the first ten natural
numbers and the square of the sum is 3025 - 385 = 2640.
Find the difference between the sum of the squares of the first one hundred
natural numbers and the square of the sum.
@verbatim[#:indent 2]|{
#lang at-exp scheme
(require (planet soegaard/infix))
(require (planet "while.scm" ("soegaard" "control.plt" 2 0))) ; while
#|
(define n 0)
(define ns 0)
(define squares 0)
(define sum 0)
@${
sum:=0;
while[ n<100,
n := n+1;
ns := ns+n;
squares := squares + n^2];
ns^2-squares
}
}|
@subsection{Example: Pythagorean Triplets}
This example is from the Euler Project.
A Pythagorean triplet is a set of three natural numbers, a,b,c for which,
a^2 + b^2 = c^2
For example, 3^2 + 4^2 = 9 + 16 = 25 = 5^2.
There exists exactly one Pythagorean triplet for which a + b + c = 1000.
Find the product abc.
@verbatim[#:indent 2]|{
#lang at-exp scheme
(require (planet soegaard/infix))
(let-values ([(a b c) (values 0 0 0)])
(let/cc return
(for ([k (in-range 1 100)])
(for ([m (in-range 2 1000)])
(for ([n (in-range 1 m)])
@${ a := k* 2*m*n;
b := k* (m^2 - n^2);
c := k* (m^2 + n^2);
when[ a+b+c = 1000,
display[{{k,m,n}, {a,b,c}}];
newline[];
return[a*b*c] ]})))))
}|
@subsection{Example: Miller Rabin Primality Test}
This example was inspired by Programming Praxis:
http://programmingpraxis.com/2009/05/01/primality-checking/
@verbatim[#:indent 2]|{
#lang at-exp scheme
(require (planet soegaard/infix))
(require srfi/27) ; random-integer
(define (factor2 n)
; return r and s, s.t n = 2^r * s where s odd
; invariant: n = 2^r * s
(let loop ([r 0] [s n])
(let-values ([(q r) (quotient/remainder s 2)])
(if (zero? r)
(loop (+ r 1) q)
(values r s)))))
(define (miller-rabin n)
; Input: n odd
(define (mod x) (modulo x n))
(define (expt x m)
(cond [(zero? m) 1]
[(even? m) @${mod[sqr[x^(m/2)] ]}]
[(odd? m) @${mod[x*x^(m-1)]}]))
(define (check? a)
(let-values ([(r s) (factor2 (sub1 n))])
; is a^s congruent to 1 or -1 modulo n ?
(and @${member[a^s,{1,mod[-1]}]} #t)))
(andmap check?
(build-list 50 (λ (_) (+ 2 (random-integer (- n 3)))))))
(define (prime? n)
(cond [(< n 2) #f]
[(= n 2) #t]
[(even? n) #f]
[else (miller-rabin n)]))
(prime? @${2^89-1})
}|

View File

@ -0,0 +1,166 @@
/* See the beginning of "scribble.css". */
/* Monospace: */
.ScmIn, .ScmRdr, .ScmPn, .ScmMeta,
.ScmMod, .ScmKw, .ScmVar, .ScmSym,
.ScmRes, .ScmOut, .ScmCmt, .ScmVal {
font-family: monospace;
}
/* Serif: */
.inheritedlbl {
font-family: serif;
}
/* ---------------------------------------- */
/* Inherited methods, left margin */
.inherited {
width: 100%;
margin-top: 0.5em;
text-align: left;
background-color: #ECF5F5;
}
.inherited td {
font-size: 82%;
padding-left: 1em;
text-indent: -0.8em;
padding-right: 0.2em;
}
.inheritedlbl {
font-style: italic;
}
/* ---------------------------------------- */
/* Scheme text styles */
.ScmIn {
color: #cc6633;
background-color: #eeeeee;
}
.ScmInBG {
background-color: #eeeeee;
}
.ScmRdr {
}
.ScmPn {
color: #843c24;
}
.ScmMeta {
color: #262680;
}
.ScmMod {
color: black;
}
.ScmOpt {
color: black;
}
.ScmKw {
color: black;
font-weight: bold;
}
.ScmErr {
color: red;
font-style: italic;
}
.ScmVar {
color: #262680;
font-style: italic;
}
.ScmSym {
color: #262680;
}
.ScmValLink {
text-decoration: none;
color: blue;
}
.ScmModLink {
text-decoration: none;
color: blue;
}
.ScmStxLink {
text-decoration: none;
color: black;
font-weight: bold;
}
.ScmRes {
color: #0000af;
}
.ScmOut {
color: #960096;
}
.ScmCmt {
color: #c2741f;
}
.ScmVal {
color: #228b22;
}
/* ---------------------------------------- */
/* Some inline styles */
.together {
width: 100%;
}
.prototype td {
vertical-align: text-top;
}
.longprototype td {
vertical-align: bottom;
}
.ScmBlk td {
vertical-align: baseline;
}
.argcontract td {
vertical-align: text-top;
}
.highlighted {
background-color: #ddddff;
}
.defmodule {
width: 100%;
background-color: #F5F5DC;
}
.specgrammar {
float: right;
}
.SBibliography td {
vertical-align: text-top;
}
.leftindent {
margin-left: 1em;
margin-right: 0em;
}
.insetpara {
margin-left: 1em;
margin-right: 1em;
}

View File

@ -0,0 +1,67 @@
// Common functionality for PLT documentation pages
function GetCookie(key, def) {
if (document.cookie.length <= 0) return def;
var i, cookiestrs = document.cookie.split(/; */);
for (i = 0; i < cookiestrs.length; i++) {
var cur = cookiestrs[i];
var eql = cur.indexOf('=');
if (eql >= 0 && cur.substring(0,eql) == key)
return unescape(cur.substring(eql+1));
}
return def;
}
function SetCookie(key, val) {
var d = new Date();
d.setTime(d.getTime()+(365*24*60*60*1000));
document.cookie =
key + "=" + escape(val) + "; expires="+ d.toGMTString() + "; path=/";
}
// note that this always stores a directory name, ending with a "/"
function SetPLTRoot(ver, relative) {
var root = location.protocol + "//" + location.host
+ NormalizePath(location.pathname.replace(/[^\/]*$/, relative));
SetCookie("PLT_Root."+ver, root);
}
// adding index.html works because of the above
function GotoPLTRoot(ver, relative) {
var u = GetCookie("PLT_Root."+ver, null);
if (u == null) return true; // no cookie: use plain up link
// the relative path is optional, default goes to the toplevel start page
if (!relative) relative = "index.html";
location = u + relative;
return false;
}
normalize_rxs = [/\/\/+/g, /\/\.(\/|$)/, /\/[^\/]*\/\.\.(\/|$)/];
function NormalizePath(path) {
var tmp, i;
for (i = 0; i < normalize_rxs.length; i++)
while ((tmp = path.replace(normalize_rxs[i], "/")) != path) path = tmp;
return path;
}
function DoSearchKey(event, field, ver, top_path) {
var val = field.value;
if (event && event.keyCode == 13) {
var u = GetCookie("PLT_Root."+ver, null);
if (u == null) u = top_path; // default: go to the top path
location = u + "search/index.html" + "?q=" + escape(val);
return false;
}
return true;
}
function TocviewToggle(glyph,id) {
var s = document.getElementById(id).style;
var expand = s.display == "none";
s.display = expand ? "block" : "none";
glyph.innerHTML = expand ? "&#9660;" : "&#9658;";
}
// `noscript' is problematic in some browsers (always renders as a
// block), use this hack instead (does not always work!)
// document.write("<style>mynoscript { display:none; }</style>");

View File

View File

@ -0,0 +1,413 @@
/* CSS seems backward: List all the classes for which we want a
particular font, so that the font can be changed in one place. (It
would be nicer to reference a font definition from all the places
that we want it.)
As you read the rest of the file, remember to double-check here to
see if any font is set. */
/* Monospace: */
.maincolumn, .refpara, .tocset, .stt, .hspace {
font-family: monospace;
}
/* Serif: */
.main, .refcontent, .tocview, .tocsub, i {
font-family: serif;
}
/* Sans-serif: */
.version, .versionNoNav {
font-family: sans-serif;
}
/* ---------------------------------------- */
p, .SIntrapara {
display: block;
margin: 1em 0;
}
h2 { /* per-page main title */
margin-top: 0;
}
h3, h4, h5, h6, h7, h8 {
margin-top: 1.75em;
margin-bottom: 0.5em;
}
/* Needed for browsers like Opera, and eventually for HTML 4 conformance.
This means that multiple paragraphs in a table element do not have a space
between them. */
table p {
margin-top: 0;
margin-bottom: 0;
}
/* ---------------------------------------- */
/* Main */
body {
color: black;
background-color: #ffffff;
}
table td {
padding-left: 0;
padding-right: 0;
}
.maincolumn {
width: 43em;
margin-right: -40em;
margin-left: 15em;
}
.main {
text-align: left;
}
/* ---------------------------------------- */
/* Navigation */
.navsettop, .navsetbottom {
background-color: #f0f0e0;
padding: 0.25em 0 0.25em 0;
}
.navsettop {
margin-bottom: 1.5em;
border-bottom: 2px solid #e0e0c0;
}
.navsetbottom {
margin-top: 2em;
border-top: 2px solid #e0e0c0;
}
.navleft {
margin-left: 1ex;
position: relative;
float: left;
white-space: nowrap;
}
.navright {
margin-right: 1ex;
position: relative;
float: right;
white-space: nowrap;
}
.nonavigation {
color: #e0e0e0;
}
.searchform {
display: inline;
margin: 0;
padding: 0;
}
.searchbox {
width: 16em;
margin: 0px;
padding: 0px;
background-color: #eee;
border: 1px solid #ddd;
text-align: center;
vertical-align: middle;
}
/* ---------------------------------------- */
/* Version */
.versionbox {
position: relative;
float: right;
left: 2em;
height: 0em;
width: 13em;
margin: 0em -13em 0em 0em;
}
.version {
font-size: small;
}
.versionNoNav {
font-size: xx-small; /* avoid overlap with author */
}
/* ---------------------------------------- */
/* Margin notes */
.refpara {
position: relative;
float: right;
left: 2em;
top: -1em;
height: 0em;
width: 13em;
margin: 0em -13em 0em 0em;
}
.refcolumn {
background-color: #F5F5DC;
display: block;
position: relative;
width: 13em;
font-size: 85%;
border: 0.5em solid #F5F5DC;
margin: 0 0 0 0;
}
.refcontent {
margin: 0 0 0 0;
}
.refcontent p {
margin-top: 0;
margin-bottom: 0;
}
/* ---------------------------------------- */
/* Table of contents, inline */
.toclink {
text-decoration: none;
color: blue;
font-size: 85%;
}
.toptoclink {
text-decoration: none;
color: blue;
font-weight: bold;
}
/* ---------------------------------------- */
/* Table of contents, left margin */
.tocset {
position: relative;
float: left;
width: 12.5em;
margin-right: 2em;
}
.tocset td {
vertical-align: text-top;
}
.tocview {
text-align: left;
background-color: #f0f0e0;
}
.tocsub {
text-align: left;
margin-top: 0.5em;
background-color: #f0f0e0;
}
.tocviewlist, .tocsublist {
margin-left: 0.2em;
margin-right: 0.2em;
padding-top: 0.2em;
padding-bottom: 0.2em;
}
.tocviewlist table {
font-size: 82%;
}
.tocviewsublist, .tocviewsublistonly, .tocviewsublisttop, .tocviewsublistbottom {
margin-left: 0.4em;
border-left: 1px solid #bbf;
padding-left: 0.8em;
}
.tocviewsublist {
margin-bottom: 1em;
}
.tocviewsublist table,
.tocviewsublistonly table,
.tocviewsublisttop table,
.tocviewsublistbottom table {
font-size: 75%;
}
.tocviewtitle * {
font-weight: bold;
}
.tocviewlink {
text-decoration: none;
color: blue;
}
.tocviewselflink {
text-decoration: underline;
color: blue;
}
.tocviewtoggle {
text-decoration: none;
color: blue;
font-size: 75%; /* looks better, and avoids bounce when toggling sub-sections due to font alignments */
}
.tocsublist td {
padding-left: 1em;
text-indent: -1em;
}
.tocsublinknumber {
font-size: 82%;
}
.tocsublink {
font-size: 82%;
text-decoration: none;
}
.tocsubseclink {
font-size: 82%;
text-decoration: none;
}
.tocsubnonseclink {
font-size: 82%;
text-decoration: none;
padding-left: 0.5em;
}
.tocsubtitle {
font-size: 82%;
font-style: italic;
margin: 0.2em;
}
.sepspace {
font-size: 40%;
}
.septitle {
font-size: 70%;
}
/* ---------------------------------------- */
/* Some inline styles */
.indexlink {
text-decoration: none;
}
.nobreak {
white-space: nowrap;
}
.stt {
}
.title {
font-size: 200%;
font-weight: normal;
margin-top: 2.8em;
text-align: center;
}
pre { margin-left: 2em; }
blockquote { margin-left: 2em; }
ol { list-style-type: decimal; }
ol ol { list-style-type: lower-alpha; }
ol ol ol { list-style-type: lower-roman; }
ol ol ol ol { list-style-type: upper-alpha; }
i {
}
.SubFlow {
display: block;
}
.boxed {
width: 100%;
background-color: #E8E8FF;
}
.hspace {
}
.slant {
font-style: oblique;
}
.badlink {
text-decoration: underline;
color: red;
}
.plainlink {
text-decoration: none;
color: blue;
}
.techoutside { text-decoration: underline; color: #b0b0b0; }
.techoutside:hover { text-decoration: underline; color: blue; }
/* .techinside:hover doesn't work with FF, .techinside:hover>
.techinside doesn't work with IE, so use both (and IE doesn't
work with inherit in the second one, so use blue directly) */
.techinside { color: black; }
.techinside:hover { color: blue; }
.techoutside:hover>.techinside { color: inherit; }
.SCentered {
text-align: center;
}
.imageleft {
float: left;
margin-right: 0.3em;
}
.Smaller{
font-size: 82%;
}
.Larger{
font-size: 122%;
}
/* A hack, inserted to break some Scheme ids: */
.mywbr {
width: 0;
font-size: 1px;
}
.compact li p {
margin: 0em;
padding: 0em;
}
.noborder img {
border: 0;
}
.SAuthorListBox {
position: relative;
float: right;
left: 2em;
top: -2.5em;
height: 0em;
width: 13em;
margin: 0em -13em 0em 0em;
}
.SAuthorList {
font-size: 82%;
}
.SAuthorList:before {
content: "by ";
}
.author {
display: inline;
white-space: nowrap;
}

10
infix/scribblings/util.ss Normal file
View File

@ -0,0 +1,10 @@
#lang scheme
(require scribble/eval
(planet cce/scheme:4:1/planet))
(provide the-eval)
(define the-eval
(let ([the-eval (make-base-eval)])
(the-eval `(require (planet ,(this-package-version-symbol))))
the-eval))

106
infix/tests/example.ss Normal file
View File

@ -0,0 +1,106 @@
#lang at-exp scheme
(require (planet soegaard/infix))
#|
Each new term in the Fibonacci sequence is generated by adding the
previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
Find the sum of all the even-valued terms in the sequence which do not
exceed four million.
|#
(require (planet "while.scm" ("soegaard" "control.plt" 2 0))) ; while
(define-values (f g t) (values 1 2 0))
(define sum f)
@${
while[ g< 4000000,
when[ even?[g], sum:=sum+g];
t := f + g;
f := g;
g := t];
sum}
#|
The sum of the squares of the first ten natural numbers is,
1^2 + 2^2 + ... + 10^2 = 385
The square of the sum of the first ten natural numbers is,
(1 + 2 + ... + 10)^2 = 552 = 3025
Hence the difference between the sum of the squares of the first ten natural
numbers and the square of the sum is 3025 - 385 = 2640.
Find the difference between the sum of the squares of the first one hundred
natural numbers and the square of the sum.|#
(define n 0)
(define ns 0)
(define squares 0)
@${
sum:=0;
while[ n<100,
n := n+1;
ns := ns+n;
squares := squares + n^2];
ns^2-squares
}
#|
A Pythagorean triplet is a set of three natural numbers, a,b,c for which,
a^2 + b^2 = c^2
For example, 3^2 + 4^2 = 9 + 16 = 25 = 5^2.
There exists exactly one Pythagorean triplet for which a + b + c = 1000.
Find the product abc.
|#
(let-values ([(a b c) (values 0 0 0)])
(let/cc return
(for ([k (in-range 1 100)])
(for ([m (in-range 2 1000)])
(for ([n (in-range 1 m)])
@${ a := k* 2*m*n;
b := k* (m^2 - n^2);
c := k* (m^2 + n^2);
when[ a+b+c = 1000,
display[{{k,m,n}, {a,b,c}}];
newline[];
return[a*b*c] ]})))))
#| Primality testing |#
(define (factor2 n)
; return r and s, s.t n = 2^r * s where s odd
; invariant: n = 2^r * s
(let loop ([r 0] [s n])
(let-values ([(q r) (quotient/remainder s 2)])
(if (zero? r)
(loop (+ r 1) q)
(values r s)))))
(require srfi/27) ; random-integer
(define (miller-rabin n)
; Input: n odd
(define (mod x) (modulo x n))
(define (expt x m)
(cond [(zero? m) 1]
[(even? m) @${mod[sqr[x^(m/2)] ]}]
[(odd? m) @${mod[x*x^(m-1)]}]))
(define (check? a)
(let-values ([(r s) (factor2 (sub1 n))])
; is a^s congruent to 1 or -1 modulo n ?
(and @${member[a^s,{1,mod[-1]}]} #t)))
(andmap check?
(build-list 50 (λ (_) (+ 2 (random-integer (- n 3)))))))
(define (prime? n)
(cond [(< n 2) #f]
[(= n 2) #t]
[(even? n) #f]
[else (miller-rabin n)]))
(prime? @${2^89-1})

226
infix/tests/test-dollar.ss Normal file
View File

@ -0,0 +1,226 @@
#lang at-exp scheme
(require "../main.rkt"
(planet schematics/schemeunit:3:4))
; <e> :== <num>
; | <id> variable reference
; | <e> [ <args> ] application
; | <e> [[ <e> ]] list reference
; | { <args> } list construction
; | (λ <ids> . <e>) lambda
; | <e> + <e> addition
; | <e> - <e> subtraction
; | <e> * <e> multiplication
; | <e> / <e> division
; | <e> ^ <e> exponentiation
; | - <e> negation
; | √ <e> square root
; | ( <e> ) grouping
; | <id> := <e> assignment
; | <e> ; <e> compound
; <args> :==
; | <e>
; | <e>, <args>+
; <id> An identifier begins with a letter,
; and is optionally followed by series of letters, digits or
; underscores.
; An underscore is read as a hyphen.
; Thus list_ref will refer to list-ref.
; <ids> A, possible empty, list of identifiers separated by white space.
; <num> A number is an non-empty series of digits,
; optionally followed by a period followed by a series of digits.
(test-case
"numbers"
(check-equal? @${0} 0)
(check-equal? @${123} 123)
(check-equal? @${12.34}12.34))
(test-case
"identifiers"
(let ([x 0] [x1 1] [x12 12] [x-y 42])
(check-equal? @${x}0)
(check-equal? @${x1}1)
(check-equal? @${x12}12)
(check-equal? @${x_y}42)))
(test-case
"application expr[arg,...]"
(check-equal? @${sin[0]}0)
(check-equal? @${quotient[7,2]}3)
(let ([thunk (lambda () 42)])
(check-equal? @${thunk[]} 42)))
(test-case
"list reference syntax list[[index]]"
(let ([xs (list 1 2 3)])
(check-equal? @${xs[[0]]} 1)
(check-equal? @${xs[[1]]} 2)
(check-equal? @${xs[[2]]} 3)))
(test-case
"anonymous function syntax (λ ids . expr)"
(check-equal? @${(λ.1)[]} 1)
(check-equal? @${(λx.x+1)[2]} 3)
(check-equal? @${(λx y.x+y+1)[1,2]} 4))
(test-case
"list construction syntax {}"
(check-equal? @${{}} '())
(check-equal? @${{1}} '(1))
(check-equal? @${{1,2}} '(1 2))
(check-equal? @${{1,2,3}} '(1 2 3)))
(test-case
"addition + with 2 or more arguments"
(check-equal? @${1+2} 3)
(check-equal? @${1+2+3} 6)
(check-equal? @${1+2+3+4} 10))
(test-case
"subtraction - with 2 or more arguments"
(check-equal? @${1-2} -1)
(check-equal? @${1-2-3} -4)
(check-equal? @${1-2-3-4} -8))
(test-case
"multiplication * with 2 or more arguments"
(check-equal? @${1*2} 2)
(check-equal? @${1*2*3} 6)
(check-equal? @${1*2*3*4} 24))
(test-case
"division / with 2 or more arguments"
(check-equal? @${120/2} 60)
(check-equal? @${120/2/3} 20)
(check-equal? @${120/2/3/4} 5))
(test-case
"exponentiation ^ with 2 or more arguments"
(check-equal? @${2^3} 8)
(check-equal? @${2^3^4} (expt 2 (expt 3 4))))
(test-case
"negation, i.e. unary -"
(check-equal? @${-1} -1)
(check-equal? @${1+-2} -1)
(check-equal? @${1--2} 3))
(test-case
"square root"
(check-equal? @${4} 2)
(check-equal? @${(2+2)} 2)
(check-equal? @${4*4} 4)
(check-equal? @${4*4} 8))
(test-case
"comparisons"
(check-equal? @${1<2} #t)
(check-equal? @${1<=2} #t)
(check-equal? @${12} #t)
(check-equal? @${1>2} #f)
(check-equal? @${1>=2} #f)
(check-equal? @${12} #f)
(check-equal? @${1<>2} #t)
(check-equal? @${2<1} #f)
(check-equal? @${2<=1} #f)
(check-equal? @${21} #f)
(check-equal? @${2>1} #t)
(check-equal? @${2>=1} #t)
(check-equal? @${21} #t)
(check-equal? @${2<=1} #f)
(check-equal? @${1<1} #f)
(check-equal? @${1<=1} #t)
(check-equal? @${11} #t)
(check-equal? @${1>1} #f)
(check-equal? @${1>=1} #t)
(check-equal? @${11} #t)
(check-equal? @${1<=1} #t)
)
(test-case
"logical negation"
(let ([t #t] [f #f])
(check-equal? @${¬t} #f)
(check-equal? @${¬f} #t)
(check-equal? @${¬1} #f)))
; TODO
#;(test-case
"assignment id := expr"
(let ([x 0])
(check-equal? (begin @${x:=1} x) 1)))
(test-case
"compound expr ; expr"
(let ([x 0] [y 3])
(check-equal? (begin @${(x:=1);(x+3)}) 4)
(check-equal? (begin @${(x:=1);x+3}) 4)
(check-equal? (begin @${x:=1;(x+3)}) 4)
(check-equal? (begin @${x:=1;x}) 1)
(check-equal? (begin @${x:=1;x;y:=x+7;y}) 8)))
(test-case
"grouping"
(check-equal? @${2*(3+4)} 14)
(check-equal? @${(3+4)*2} 14)
(check-equal? @${5*(3+4)*2} 70))
(test-case
"precedence of + and *"
(check-equal? @${1+2*3} 7)
(check-equal? @${2*3+4} 10)
(check-equal? @${2+3*4+5} 19))
#;(do comments still work? @${1+2})
(test-case
"quoting"
(check-equal? @$quote{1+2} '(#%infix (+ 1 2))))
(test-case
"syntax-quoting"
(check-equal? (syntax->datum @$quote-syntax{1+2}) '(#%infix (+ 1 2))))
(test-case
"under score"
(check-equal? @${list_ref[{1,2,3}, 0]} 1))
(require scheme/stxparam)
(test-case
"#%infix"
(check-equal? (syntax-parameterize ((#%infix (λ (x) #'42))) @${1+2}) 42)
(check-equal?
(syntax-parameterize ([#%infix (syntax-rules () [(_ e) (+ e 1)])]) @${2})
3))
(test-case
"rebound +"
(check-equal? (let ([+ -]) @${1+2}) -1))
(test-case
"precedence"
(check-equal? @${1+cos[0]} 2))
(test-case
"function definition"
(check-equal? (let ([x 1]) @${f(x):=x+1} (f 1)) 2))
(test-case
"strings"
(check-equal? @${"foo"} "foo"))

215
infix/tests/test-dollar.ss~ Normal file
View File

@ -0,0 +1,215 @@
#lang at-exp scheme
(require (planet soegaard/infix)
(planet schematics/schemeunit:3:4))
; <e> :== <num>
; | <id> variable reference
; | <e> [ <args> ] application
; | <e> [[ <e> ]] list reference
; | { <args> } list construction
; | (λ <ids> . <e>) lambda
; | <e> + <e> addition
; | <e> - <e> subtraction
; | <e> * <e> multiplication
; | <e> / <e> division
; | <e> ^ <e> exponentiation
; | - <e> negation
; | √ <e> square root
; | ( <e> ) grouping
; | <id> := <e> assignment
; | <e> ; <e> compound
; <args> :==
; | <e>
; | <e>, <args>+
; <id> An identifier begins with a letter,
; and is optionally followed by series of letters, digits or
; underscores.
; An underscore is read as a hyphen.
; Thus list_ref will refer to list-ref.
; <ids> A, possible empty, list of identifiers separated by white space.
; <num> A number is an non-empty series of digits,
; optionally followed by a period followed by a series of digits.
(test-case
"numbers"
(check-equal? @${0} 0)
(check-equal? @${123} 123)
(check-equal? @${12.34}12.34))
(test-case
"identifiers"
(let ([x 0] [x1 1] [x12 12] [x-y 42])
(check-equal? @${x}0)
(check-equal? @${x1}1)
(check-equal? @${x12}12)
(check-equal? @${x_y}42)))
(test-case
"application expr[arg,...]"
(check-equal? @${sin[0]}0)
(check-equal? @${quotient[7,2]}3)
(let ([thunk (lambda () 42)])
(check-equal? @${thunk[]} 42)))
(test-case
"list reference syntax list[[index]]"
(let ([xs (list 1 2 3)])
(check-equal? @${xs[[0]]} 1)
(check-equal? @${xs[[1]]} 2)
(check-equal? @${xs[[2]]} 3)))
(test-case
"anonymous function syntax (λ ids . expr)"
(check-equal? @${(λ.1)[]} 1)
(check-equal? @${(λx.x+1)[2]} 3)
(check-equal? @${(λx y.x+y+1)[1,2]} 4))
(test-case
"list construction syntax {}"
(check-equal? @${{}} '())
(check-equal? @${{1}} '(1))
(check-equal? @${{1,2}} '(1 2))
(check-equal? @${{1,2,3}} '(1 2 3)))
(test-case
"addition + with 2 or more arguments"
(check-equal? @${1+2} 3)
(check-equal? @${1+2+3} 6)
(check-equal? @${1+2+3+4} 10))
(test-case
"subtraction - with 2 or more arguments"
(check-equal? @${1-2} -1)
(check-equal? @${1-2-3} -4)
(check-equal? @${1-2-3-4} -8))
(test-case
"multiplication * with 2 or more arguments"
(check-equal? @${1*2} 2)
(check-equal? @${1*2*3} 6)
(check-equal? @${1*2*3*4} 24))
(test-case
"division / with 2 or more arguments"
(check-equal? @${120/2} 60)
(check-equal? @${120/2/3} 20)
(check-equal? @${120/2/3/4} 5))
(test-case
"exponentiation ^ with 2 or more arguments"
(check-equal? @${2^3} 8)
(check-equal? @${2^3^4} (expt 2 (expt 3 4))))
(test-case
"negation, i.e. unary -"
(check-equal? @${-1} -1)
(check-equal? @${1+-2} -1)
(check-equal? @${1--2} 3))
(test-case
"square root"
(check-equal? @${4} 2)
(check-equal? @${(2+2)} 2)
(check-equal? @${4*4} 4)
(check-equal? @${4*4} 8))
(test-case
"comparisons"
(check-equal? @${1<2} #t)
(check-equal? @${1<=2} #t)
(check-equal? @${12} #t)
(check-equal? @${1>2} #f)
(check-equal? @${1>=2} #f)
(check-equal? @${12} #f)
(check-equal? @${1<>2} #t)
(check-equal? @${2<1} #f)
(check-equal? @${2<=1} #f)
(check-equal? @${21} #f)
(check-equal? @${2>1} #t)
(check-equal? @${2>=1} #t)
(check-equal? @${21} #t)
(check-equal? @${2<=1} #f)
(check-equal? @${1<1} #f)
(check-equal? @${1<=1} #t)
(check-equal? @${11} #t)
(check-equal? @${1>1} #f)
(check-equal? @${1>=1} #t)
(check-equal? @${11} #t)
(check-equal? @${1<=1} #t)
)
(test-case
"logical negation"
(let ([t #t] [f #f])
(check-equal? @${¬t} #f)
(check-equal? @${¬f} #t)
(check-equal? @${¬1} #f)))
(test-case
"assignment id := expr"
(let ([x 0])
(check-equal? (begin @${x:=1} x) 1)))
(test-case
"compound expr ; expr"
(let ([x 0] [y 3])
(check-equal? (begin @${(x:=1);(x+3)}) 4)
(check-equal? (begin @${(x:=1);x+3}) 4)
(check-equal? (begin @${x:=1;(x+3)}) 4)
(check-equal? (begin @${x:=1;x}) 1)
(check-equal? (begin @${x:=1;x;y:=x+7;y}) 8)))
(test-case
"grouping"
(check-equal? @${2*(3+4)} 14)
(check-equal? @${(3+4)*2} 14)
(check-equal? @${5*(3+4)*2} 70))
(test-case
"precedence of + and *"
(check-equal? @${1+2*3} 7)
(check-equal? @${2*3+4} 10)
(check-equal? @${2+3*4+5} 19))
#;(do comments still work? @${1+2})
(test-case
"quoting"
(check-equal? @$quote{1+2} '(#%infix (+ 1 2))))
(test-case
"syntax-quoting"
(check-equal? (syntax->datum @$quote-syntax{1+2}) '(#%infix (+ 1 2))))
(test-case
"under score"
(check-equal? @${list_ref[{1,2,3}, 0]} 1))
(require scheme/stxparam)
(test-case
"#%infix"
(check-equal? (syntax-parameterize ((#%infix (λ (x) #'42))) @${1+2}) 42)
(check-equal?
(syntax-parameterize ([#%infix (syntax-rules () [(_ e) (+ e 1)])]) @${2})
3))
(test-case
"rebound +"
(check-equal? (let ([+ -]) @${1+2}) -1))
(test-case
"precedence"
(check-equal? @${1+cos[0]} 2))

View File

@ -0,0 +1,296 @@
#lang scheme
(require "parameter.ss")
;;;
;;; NOTES:
;;; Changes from planet version: ]] (CDB) Bug fixed
;;; Strings are supported.
;;; Assignments changed from set! to define.
;;; Assignment of functions.
;;; Bug fix: identifiers with more than one _ wasn't converted correctly
; <e> = <num>
; | <id> variable reference
; | <e> [ <args> ] application
; | { <args> } list construction
; | <e> + <e> addition
; | <e> - <e> subtraction
; | <e> * <e> multiplication
; | <e> / <e> division
; | <e> ^ <e> exponentiation
; | - <e> negation
; | ( <e> ) grouping
; <id> An identifier begins with a letter,
; and is optionally followed by series of letters, digits or underscores.
; An underscore is converted to a -. Thus list_ref will refer to list-ref.
; <num> A number is an non-empty series of digits,
; optionally followed by a period followed by a series of digits.
; <string> A number is a " followed by a series of non-" characters followed by a " .
(provide parse-expression parse-expression-from-port parse-math-string)
(require parser-tools/yacc
parser-tools/lex
(prefix-in : parser-tools/lex-sre)
syntax/readerr)
(define-tokens value-tokens (NUMBER IDENTIFIER STRING))
(define-empty-tokens op-tokens (newline :=
OP CP ; ( )
OB CB ; [ ]
OC CC ; { }
ODB ; [[ ]]
COMMA ; ,
SEMI ; ;
PERIOD ; .
LAMBDA ; lambda or λ
SQRT ; √
NEG ; ¬ (logical negation)
LESS-EQUAL ; <= or ≤
GREATER-EQUAL ; >= or ≥
NOT-EQUAL ; <> or ≠
= < >
+ - * / ^
EOF))
(define-lex-abbrevs
[letter (:or (:/ "a" "z") (:/ #\A #\Z) )]
[digit (:/ #\0 #\9)]
[string (:: #\" (:* (:or letter digit #\_ #\?)) #\")]
[identifier (:: letter (:* (:or letter digit #\_ #\?)))])
(define expression-lexer
(lexer-src-pos
[(eof) 'EOF]
[(:or #\tab #\space #\newline) ; this skips whitespace
(return-without-pos (expression-lexer input-port))]
[#\newline (token-newline)] ; (token-newline) returns 'newline
[(:or ":=" "+" "-" "*" "/" "^" "<" ">" "=" "\"") (string->symbol lexeme)]
["(" 'OP]
[")" 'CP]
["[" 'OB]
["]" 'CB]
["{" 'OC]
["}" 'CC]
["[[" 'ODB]
; ["]]" 'CDB]
["," 'COMMA]
[";" 'SEMI]
["." 'PERIOD]
[#\λ 'LAMBDA]
["lambda" 'LAMBDA]
["" 'SQRT]
["¬" 'NEG]
["" 'LESS-EQUAL]
["<=" 'LESS-EQUAL]
["" 'GREATER-EQUAL]
[">=" 'GREATER-EQUAL]
["<>" 'NOT-EQUAL]
["" 'NOT-EQUAL]
[string
(token-STRING (substring lexeme 1 (- (string-length lexeme) 1)))]
[identifier
(token-IDENTIFIER (string->symbol (regexp-replace* #rx"_" lexeme "-")))]
[(:+ digit) (token-NUMBER (string->number lexeme))]
[(:: (:+ digit) #\. (:* digit)) (token-NUMBER (string->number lexeme))]))
;; A macro to build the syntax object
(define-syntax (b stx)
(syntax-case stx ()
((_ o value start end)
(with-syntax
((start-pos (datum->syntax #'start
(string->symbol
(format "$~a-start-pos"
(syntax->datum #'start)))))
(end-pos (datum->syntax #'end
(string->symbol
(format "$~a-end-pos"
(syntax->datum #'end))))))
#`(datum->syntax o
value
(list (if (syntax? o) (syntax-source o) 'missing-in-action--sorry)
(if o (+ (syntax-line o) (position-line start-pos) -1) #f)
(if o (+ (syntax-column o) (position-offset start-pos) ) #f)
(if o (+ (syntax-position o) (position-offset start-pos)) #f)
(- (position-offset end-pos)
(position-offset start-pos)))
o o)))))
; for testing: builds lists instead of syntax objects
#;(define-syntax (b stx)
(syntax-case stx ()
[(_ _ val _ _)
#'val]))
(define (display-position-token pos)
(display (list (position-offset pos)
(position-line pos)
(position-col pos))))
(define (expression-parser source-name orig-stx)
(define o orig-stx)
(parser
(src-pos)
(suppress) ; hmm...
(start start)
(end newline EOF)
(tokens value-tokens op-tokens)
(error (lambda (token-ok? name val start end)
; The first argument will be #f if and only if the error is that an invalid token was received.
; The second and third arguments will be the name and the value of the token at which the error was detected.
; The fourth and fifth arguments, if present, provide the source positions of that token.
(unless #f #; (string? (syntax->datum o))
(display "DEBUG: ")
(display (list o token-ok? name val start end))
(display-position-token start) (newline)
(display-position-token end) (newline)
(newline))
(raise-syntax-error
'expression-parser "parse error" o
(datum->syntax
o
(if (string? (syntax->datum o))
(substring (syntax->datum o)
(max 0 (- (position-offset start) 1))
(min (- (position-offset end) 1)
(string-length (syntax->datum o))))
(begin
(display o)
(newline)
"fooooooooo"))
(list (if (syntax? o) (syntax-source o) 'missing-in-action--sorry)
(if o (+ (syntax-line o) (position-line start) -1) #f)
(if o (+ (syntax-column o) (position-offset start)) #f)
(if o (+ (syntax-position o) (position-offset start)) #f)
(- (position-offset end)
(position-offset start)))))))
(precs (right :=)
(left - +)
(left * /)
(right OB)
(right ^)
(left =) ; comparisons
(right NEG)
(left SEMI))
(grammar
(start [(exp) (b o `(#%infix ,$1) 1 1)]
[() #f])
;; If there is an error, ignore everything before the error
;; and try to start over right after the error
(args [(exp) (b o (list $1) 1 1)]
[(exp COMMA args) (b o (cons $1 $3) 1 3)]
[() '()])
(ids [() '()]
[(IDENTIFIER ids) (b o (cons $1 $2) 1 2)])
(parenthensis-exp
[(OP exp CP) $2])
(atom
[(NUMBER) (b o $1 1 1)]
[(IDENTIFIER) (b o $1 1 1)]
[(STRING) (b o $1 1 1)]
[(parenthensis-exp) $1])
(construction-exp
[(OC args CC) (b o `(,(b o 'list 1 3) ,@$2) 1 3)]
[(OP LAMBDA ids PERIOD exp CP) (b o `(,(b o 'lambda 2 2) ,$3 ,$5) 1 6)]
[(atom) $1])
(application-exp
[(application-exp OB args CB) (b o `(,$1 ,@$3) 1 4)] ; function application
[(application-exp ODB exp CB CB) (b o `(,(b o 'list-ref 1 4) ,$1 ,$3) 1 4)] ; list ref
[(construction-exp) $1])
#;(implicit-exp
[(application-exp application-exp) (prec *) (b o `(,(b o '* 1 2) ,$1 ,$2) 1 2)] ; implicit
[(application-exp) $1])
(power-exp
[(application-exp ^ power-exp) (prec ^) (b o `(expt ,$1 ,$3) 1 3)]
[(application-exp) $1])
(sqrt-exp
[(SQRT sqrt-exp) (b o `(,(b o 'sqrt 1 1) ,$2) 1 2)]
[(power-exp) $1])
(negation-exp
[(- negation-exp) (b o `(,(b o '- 1 1) ,$2) 1 2)]
[(sqrt-exp) $1])
(multiplication-exp
[(multiplication-exp * negation-exp) (prec *) (b o `(,(b o '* 2 2) ,$1 ,$3) 1 3)]
[(multiplication-exp / negation-exp) (prec /) (b o `(,(b o '/ 2 2) ,$1 ,$3) 1 3)]
;[(multiplication-exp negation-exp) (prec *) (b o `(,(b o '* 1 2) ,$1 ,$2) 1 2)]
[(negation-exp) $1])
(addition-exp
[(addition-exp - multiplication-exp) (prec -) (b o `(,(b o '- 2 2) ,$1 ,$3) 1 3)]
[(addition-exp + multiplication-exp) (prec +) (b o `(,(b o '+ 2 2) ,$1 ,$3) 1 3)]
[(multiplication-exp) $1])
(order-exp
[(addition-exp LESS-EQUAL addition-exp) (prec =) (b o `(,(b o '<= 2 2) ,$1 ,$3) 1 3)]
[(addition-exp < addition-exp) (prec =) (b o `(,(b o '< 2 2) ,$1 ,$3) 1 3)]
[(addition-exp GREATER-EQUAL addition-exp) (prec =) (b o `(,(b o '>= 2 2) ,$1 ,$3) 1 3)]
[(addition-exp > addition-exp) (prec =) (b o `(,(b o '> 2 2) ,$1 ,$3) 1 3)]
[(addition-exp NOT-EQUAL addition-exp) (prec =) (b o `(not (,(b o '= 2 2) ,$1 ,$3)) 1 3)]
[(addition-exp = addition-exp) (prec =) (b o `(,(b o '= 2 2) ,$1 ,$3) 1 3)]
[(addition-exp) $1])
(logical-negation-exp
[(NEG logical-negation-exp) (prec NEG) (b o `(,(b o 'not 1 1) ,$2) 1 2)]
[(order-exp) $1])
(assignment-exp
[(IDENTIFIER := assignment-exp) (b o `(,(b o 'define 2 2) ,$1 ,$3) 1 3)]
[(IDENTIFIER OP IDENTIFIER CP := assignment-exp) (b o `(,(b o 'define 3 3) (,$1 ,$3) ,$6) 1 6)]
[(logical-negation-exp) $1])
(compound-exp
[(compound-exp SEMI assignment-exp) (b o `(,(b o 'begin 2 2) ,$1 ,$3) 1 3)]
[(assignment-exp) $1])
(exp
[(compound-exp) $1]))))
;; run the calculator on the given input-port
(define (parse-expression-from-port ip)
(port-count-lines! ip)
(letrec ((one-line
(lambda ()
(let ((result ((expression-parser "test" #f)
(λ () (expression-lexer ip)))))
(when result
(printf "~a~n" result)
(one-line))))))
(one-line)))
(define (parse-expression stx ip)
(port-count-lines! ip)
((expression-parser stx stx) (λ () (expression-lexer ip))))
(define parse-math-string
(case-lambda
[(s)
(display (format "~a\n" s))
(parse-math-string s (let ([here #'here]) (datum->syntax here s here)))]
[(s src)
(cond
[(string? s)
(parse-expression src (open-input-string s))]
[(special-comment? s)
s]
[else
(if (or (symbol? s) (boolean? s))
s
(datum->syntax (second s) (cons 'quote-syntax (cdr s))))])]))

202
math-scribble/MathJax/COPYING.txt vendored Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

43
math-scribble/MathJax/MathJax.js vendored Normal file

File diff suppressed because one or more lines are too long

55
math-scribble/MathJax/README.txt vendored Normal file
View File

@ -0,0 +1,55 @@
OVERVIEW:
MathJax is an open-source JavaScript display engine for LaTeX and
MathML that works in all modern browsers. It was designed with the
goal of consolidating the recent advances in web technologies into a
single, definitive, math-on-the-web platform supporting the major
browsers and operating systems. It requires no setup on the part of
the user (no plugins to downlaod or software to install), so the page
author can write web documents that include mathematics and be
confident that users will be able to view it naturally and easily.
One simply includes MathJax and some mathematics in a web page, and
MathJax does the rest.
Some of the main features of MathJax include:
o High-quality display of LaTeX and MathML math notation in HTML pages
o Supported in most browsers with no plug-ins, extra fonts, or special
setup for the reader
o Easy for authors, flexible for publishers, extensible for developers
o Supports math accessibility, cut and paste interoperability and other
advanced functionality
o Powerful API for integration with other web applications
See http://www.mathjax.org/ for additional details.
INSTALLATION AND USAGE:
The MathJax installation and usage documentation is available on the
docs/html directory of the MathJax distribution (see
docs/html/index.html for the starting point). The documents are also
available on the MathJax web site on line at
http://www.mathjax.org/docs/
COMMUNITY:
The main MathJax website is www.mathjax.org, and it includes announcements
and other important information. MathJax also has a SourceForge site at
http://sourceforge.net/projects/mathjax/ that includes the download site
for the MathJax distribution, the bug-tracker for reporting bugs, and
several user forums for asking questions and getting assistance:
Bug tracker: http://sourceforge.net/tracker/?group_id=261188&atid=1240827
MathJax Help: http://sourceforge.net/projects/mathjax/forums/forum/948701
Open Discussion: http://sourceforge.net/projects/mathjax/forums/forum/948700
Before reporting a bug, please check that it has not already been reported.
Also, please use the bug tracker for reporting bugs rather than the help
forum.

View File

@ -0,0 +1,18 @@
/*
* ../SourceForge/trunk/mathjax/config/MMLorHTML.js
*
* Copyright (c) 2010 Design Science, Inc.
*
* Part of the MathJax library.
* See http://www.mathjax.org for details.
*
* Licensed under the Apache License, Version 2.0;
* you may not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
MathJax.Unpack([
['(function(c){var a=','MathJax.Hub','.Insert({prefer:{MSIE:"MML",Firefox:"MML",Opera:"HTML",other:"HTML"}},(',1,'.config.MMLorHTML||{}));var f={Firefox:3,Opera:9.52,MSIE:6,Chrome:0.3,Safari:2,Konqueror:4};var b=(c','.Browser','.version==="0.0"||','c.Browser.versionAtLeast','(f[c',5,']||0));var h;try{new ActiveXObject("MathPlayer.Factory.1");h=true}catch(g){h=false}var e=(c',5,'.isFirefox&&',7,'("1.5"))||(c',5,'.isMSIE&&h)||(c',5,'.isOpera&&',7,'("9.52"));var d=(a.prefer&&typeof(a.prefer)==="object"?a.prefer[',1,5,']||a.prefer.other||"HTML":a.prefer);if(b||e){if(e&&(d==="MML"||!b)){','c.config.jax.unshift("output/','NativeMML")}else{',24,'HTML-CSS")}}else{c.PreProcess','.disabled=true;','c.prepareScripts',28,'MathJax.Message.Set("Your browser does not support MathJax",null,4000);c.Startup.signal.Post("MathJax not supported")}})(',1,');MathJax.Ajax.loadComplete("[MathJax]/config/MMLorHTML.js");']
]);

590
math-scribble/MathJax/config/MathJax.js vendored Normal file
View File

@ -0,0 +1,590 @@
/*************************************************************
*
* MathJax/config/MathJax.js
*
* This configuration file is loaded when there is no explicit
* configuration script in the <script> tag that loads MathJax.js
*
* Use it to customize the MathJax settings. See comments below.
*
* ---------------------------------------------------------------------
*
* Copyright (c) 2009-10 Design Science, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
MathJax.Hub.Config({
//
// A comma-separated list of configuration files to load
// when MathJax starts up. E.g., to define local macros, etc.
// The default directory is the MathJax/config directory.
//
// Example: config: ["local/local.js"],
// Example: config: ["local/local.js","MMLtoHTML.js"],
//
config: [],
//
// A comma-separated list of CSS stylesheet files to be loaded
// when MathJax starts up. The default directory is the
// MathJax/config directory.
//
// Example: styleSheets: ["MathJax.css"],
//
styleSheets: [],
//
// Styles to be defined dynamically at startup time.
//
// Example:
// styles: {
// ".MathJax .merror": {
// color: "blue",
// "background-color": "green"
// }
// },
//
styles: {},
//
// A comma-separated list of input and output jax to initialize at startup.
// Their main code is loaded only when they are actually used, so it is not
// inefficient to include jax that may not actually be used on the page. These
// are found in the MathJax/jax directory.
//
jax: ["input/TeX","output/HTML-CSS"],
//
// A comma-separated list of extensions to load at startup. The default
// directory is MathJax/extensions.
//
// Example: extensions: ["tex2jax.js","TeX/AMSmath.js","TeX/AMSsymbols.js"],
//
extensions: ["tex2jax.js", "TeX/AMSmath.js", "TeX/AMSsymbols.js"],
//
// Patterns to remove from before and after math script tags. If you are not
// using one of the preprocessors (e.g., tex2jax), you need to insert something
// extra into your HTML file in order to avoid a bug in Internet Explorer. IE
// removes spaces from the DOM that it thinks are redundent, and since a SCRIPT
// tag usually doesn't add content to the page, if there is a space before and after
// a MathJax SCRIPT tag, IE will remove the first space. When MathJax inserts
// the typeset mathematics, this means there will be no space before it and the
// preceeding text. In order to avoid this, you should include some "guard characters"
// before or after the math SCRIPT tag; define the patterns you want to use below.
// Note that these are used as regular expressions, so you will need to quote
// special characters. Furthermore, since they are javascript strings, you must
// quote javascript special characters as well. So to obtain a backslash, you must
// use \\ (doubled for javascript). For example, "\\[" is the pattern \[ in the
// regular expression. That means that if you want an actual backslash in your
// guard characters, you need to use "\\\\" in order to get \\ in the regular
// expression, and \ in the actual text. If both preJax and postJax are defined,
// both must be present in order to be removed.
//
// See also the preRemoveClass comments below.
//
// Example:
// preJax: "\\\\\\\\", // makes a double backslash the preJax text
// or
// preJax: "\\[\\[", // jax scripts must be enclosed in double brackets
// postJax: "\\]\\]",
//
preJax: null,
postJax: null,
//
// The CSS class for a math preview to be removed preceeding a MathJax
// SCRIPT tag. If the tag just before the MathJax SCRIPT tag is of this
// class, its contents are removed when MathJax processes the SCRIPT
// tag. This allows you to include a math preview in a form that will
// be displayed prior to MathJax performing its typesetting. It also
// avoids the Internet Explorer space-removal bug, and can be used in
// place of preJax and postJax if that is more convenient.
//
// For example
//
// <span class="MathJax_Preview">[math]</span><script type="math/tex">...</script>
//
// would display "[math]" in place of the math until MathJax is able to typeset it.
//
preRemoveClass: "MathJax_Preview",
//
// This value controls whether the "Processing Math: nn%" message are displayed
// in the lower left-hand corner. Set to "false" to prevent those messages (though
// file loading and other messages will still be shown).
//
showProcessingMessages: true,
//
// This value controls the verbosity of the messages in the lower left-hand corner.
// Set it to "none" to eliminate all messages, or set it to "simple" to show
// "Loading..." and "Processing..." rather than showing the full file name and the
// percentage of the mathematics processed.
//
messageStyle: "normal",
//
// These two parameters control the alignment and shifting of displayed equations.
// The first can be "left", "center", or "right", and determines the alignment of
// displayed equations. When the alignment is not "center", the second determines
// an indentation from the left or right side for the displayed equations.
//
displayAlign: "center",
displayIndent: "0em",
//
// Normally MathJax will perform its starup commands (loading of
// configuration, styles, jax, and so on) as soon as it can. If you
// expect to be doing additional configuration on the page, however, you
// may want to have it wait until the page's onload hander is called. If so,
// set this to "onload".
//
delayStartupUntil: "none",
//
// Normally MathJax will typeset the mathematics on the page as soon as
// the page is loaded. If you want to delay that process, in which case
// you will need to call MathJax.Hub.Typeset() yourself by hand, set
// this value to true.
//
skipStartupTypeset: false,
//============================================================================
//
// These parameters control the tex2jax preprocessor (when you have included
// "tex2jax.js" in the extensions list above).
//
tex2jax: {
//
// The Id of the element to be processed (defaults to full document)
//
element: null,
//
// The delimiters that surround in-line math expressions. The first in each
// pair is the initial delimiter and the second is the terminal delimiter.
// Comment out any that you don't want, but be sure there is no extra
// comma at the end of the last item in the list -- some browsers won't
// be able to handle that.
//
inlineMath: [
['$','$'], // uncomment this for standard TeX math delimiters
['\\(','\\)']
],
//
// The delimiters that surround displayed math expressions. The first in each
// pair is the initial delimiter and the second is the terminal delimiter.
// Comment out any that you don't want, but be sure there is no extra
// comma at the end of the last item in the list -- some browsers won't
// be able to handle that.
//
displayMath: [
['$$','$$'],
['\\[','\\]']
],
//
// This array lists the names of the tags whose contents should not be
// processed by tex2jax (other than to look for ignore/process classes
// as listed below). You can add to (or remove from) this list to prevent
// MathJax from processing mathematics in specific contexts.
//
skipTags: ["script","noscript","style","textarea","pre","code"],
//
// This is the class name used to mark elements whose contents should
// not be processed by tex2jax (other than to look for the
// processClass pattern below). Note that this is a regular
// expression, and so you need to be sure to quote any regexp special
// characters. The pattern is automatically preceeded by '(^| )(' and
// followed by ')( |$)', so your pattern will have to match full words
// in the class name. Assigning an element this class name will
// prevent `tex2jax` from processing its contents.
//
ignoreClass: "tex2jax_ignore",
//
// This is the class name used to mark elements whose contents SHOULD
// be processed by tex2jax. This is used to turn on processing within
// tags that have been marked as ignored or skipped above. Note that
// this is a regular expression, and so you need to be sure to quote
// any regexp special characters. The pattern is automatically
// preceeded by '(^| )(' and followed by ')( |$)', so your pattern
// will have to match full words in the class name. Use this to
// restart processing within an element that has been marked as
// ignored above.
//
processClass: "tex2jax_process",
//
// Set to "true" to allow \$ to produce a dollar without starting in-line
// math mode. If you uncomment the ['$','$'] line above, you should change
// this to true so that you can insert plain dollar signs into your documents
//
processEscapes: true,
//
// Controls whether tex2jax processes LaTeX environments outside of math
// mode. Set to "false" to prevent processing of environments except within
// math mode.
//
processEnvironments: true,
//
// Controls whether tex2jax inserts MathJax_Preview spans to make a
// preview available, and what preview to use, when it locates in-line
// and display mathetics on the page. The default is "TeX", which
// means use the TeX code as the preview (until it is processed by
// MathJax). Set to "none" to prevent the previews from being
// inserted (the math will simply disappear until it is typeset). Set
// to an array containing the description of an HTML snippet in order
// to use the same preview for all equations on the page (e.g., you
// could have it say "[math]" or load an image).
//
// E.g., preview: ["[math]"],
// or preview: [["img",{src: "http://myserver.com/images/mypic.jpg"}]]
//
preview: "TeX"
},
//============================================================================
//
// These parameters control the mml2jax preprocessor (when you have included
// "mml2jax.js" in the extensions list above).
//
mml2jax: {
//
// The Id of the element to be processed (defaults to full document)
//
element: null,
//
// Controls whether mml2jax inserts MathJax_Preview spans to make a
// preview available, and what preview to use, whrn it locates
// mathematics on the page. The default is "alttext", which means use
// the <math> tag's alttext attribute as the preview (until it is
// processed by MathJax), if the tag has one. Set to "none" to
// prevent the previews from being inserted (the math will simply
// disappear until it is typeset). Set to an array containing the
// description of an HTML snippet in order to use the same preview for
// all equations on the page (e.g., you could have it say "[math]" or
// load an image).
//
// E.g., preview: ["[math]"],
// or preview: [["img",{src: "http://myserver.com/images/mypic.jpg"}]]
//
preview: "alttext"
},
//============================================================================
//
// These parameters control the jsMath2jax preprocessor (when you have included
// "jsMath2jax.js" in the extensions list above).
//
jsMath2jax: {
//
// The Id of the element to be processed (defaults to full document)
//
element: null,
//
// Controls whether jsMath2jax inserts MathJax_Preview spans to make a
// preview available, and what preview to use, when it locates
// mathematics on the page. The default is "TeX", which means use the
// TeX code as the preview (until it is processed by MathJax). Set to
// "none" to prevent the previews from being inserted (the math will
// simply disappear until it is typeset). Set to an array containing
// the description of an HTML snippet in order to use the same preview
// for all equations on the page (e.g., you could have it say "[math]"
// or load an image).
//
// E.g., preview: ["[math]"],
// or preview: [["img",{src: "http://myserver.com/images/mypic.jpg"}]]
//
preview: "TeX"
},
//============================================================================
//
// These parameters control the TeX input jax.
//
TeX: {
//
// This specifies the side on which \tag{} macros will place the tags.
// Set to "left" to place on the left-hand side.
//
TagSide: "right",
//
// This is the amound of indentation (from right or left) for the tags.
//
TagIndent: ".8em",
//
// This is the width to use for the multline environment
//
MultLineWidth: "85%",
//
// List of macros to define. These are of the form
// name: value
// where 'value' is the replacement text for the macro \name.
// The 'value' can also be [value,n] where 'value' is the replacement
// text and 'n' is the number of parameters for the macro.
// Note that backslashes must be doubled in the replacement string.
//
// E.g.,
//
// Macros: {
// RR: '{\\bf R}',
// bold: ['{\\bf #1}', 1]
// }
//
Macros: {}
},
//============================================================================
//
// These parameters control the MathML inupt jax.
//
MathML: {
//
// This specifies whether to use TeX spacing or MathML spacing when the
// HTML-CSS output jax is used.
//
useMathMLspacing: false
},
//============================================================================
//
// These parameters control the HTML-CSS output jax.
//
"HTML-CSS": {
//
// This controls the global scaling of mathematics as compared to the
// surrounding text. Values between 100 and 133 are usually good choices.
//
scale: 100,
//
// This is a list of the fonts to look for on a user's computer in
// preference to using MathJax's web-based fonts. These must
// correspond to directories available in the jax/output/HTML-CSS/fonts
// directory, where MathJax stores data about the characters available
// in the fonts. Set this to ["TeX"], for example, to prevent the
// use of the STIX fonts, or set it to an empty list, [], if
// you want to force MathJax to use web-based or image fonts.
//
availableFonts: ["STIX","TeX"],
//
// This is the preferred font to use when more than one of those
// listed above is available.
//
preferredFont: "TeX",
//
// This is the web-based font to use when none of the fonts listed
// above are available on the user's computer. Note that currently
// only the TeX font is available in a web-based form. Set this to
//
// webFont: null,
//
// if you want to prevent the use of web-based fonts.
//
webFont: "TeX",
//
// This is the font to use for image fallback mode (when none of the
// fonts listed above are available and the browser doesn't support
// web-fonts via the @font-face CSS directive). Note that currently
// only the TeX font is available as an image font. Set this to
//
// imageFont: null,
//
// if you want to prevent the use of image fonts (e.g., you have not
// installed the image fonts on your server). In this case, only
// browsers that support web-based fonts will be able to view your pages
// without having the fonts installed on the client computer. The browsers
// that support web-based fonts include: IE6 and later, Chrome, Safari3.1
// and above, Firefox3.5 and later, and Opera10 and later. Note that
// Firefox3.0 is NOT on this list, so without image fonts, FF3.0 users
// will be required to to download and install either the STIX fonts or the
// MathJax TeX fonts.
//
imageFont: "TeX",
//
// This controls whether the MathJax contextual menu will be available
// on the mathematics in the page. If true, then right-clicking (on
// the PC) or control-clicking (on the Mac) will produce a MathJax
// menu that allows you to get the source of the mathematics in
// various formats, change the size of the mathematics relative to the
// surrounding text, and get information about MathJax.
//
// Set this to false to disable the menu. When true, the MathMenu
// items below configure the actions of the menu.
//
showMathMenu: true,
//
// This allows you to define or modify the styles used to display
// various math elements created by MathJax.
//
// Example:
// styles: {
// ".MathJax_Preview": {
// "font-size": "80%", // preview uses a smaller font
// color: "red" // and is in red
// }
// }
//
styles: {},
//
// Configuration for <maction> tooltips
// (see also the #MathJax_Tooltip CSS in MathJax/jax/output/HTML-CSS/config.js,
// which can be overriden using the styles values above).
//
tooltip: {
delayPost: 600, // milliseconds delay before tooltip is posted after mouseover
delayClear: 600, // milliseconds delay before tooltip is cleared after mouseout
offsetX: 10, offsetY: 5 // pixels to offset tooltip from mouse position
}
},
//============================================================================
//
// These parameters control the NativeMML output jax.
//
NativeMML: {
//
// This controls the global scaling of mathematics as compared to the
// surrounding text. Values between 100 and 133 are usually good choices.
//
scale: 100,
//
// This controls whether the MathJax contextual menu will be available
// on the mathematics in the page. If true, then right-clicking (on
// the PC) or control-clicking (on the Mac) will produce a MathJax
// menu that allows you to get the source of the mathematics in
// various formats, change the size of the mathematics relative to the
// surrounding text, and get information about MathJax.
//
// Set this to false to disable the menu. When true, the MathMenu
// items below configure the actions of the menu.
//
// There is a separate setting for MSIE, since the code to handle that
// is a bit delicate; if it turns out to have unexpected consequences,
// you can turn it off without turing off other browser support.
//
showMathMenu: true,
showMathMenuMSIE: true,
//
// This allows you to define or modify the styles used to display
// various math elements created by MathJax.
//
// Example:
// styles: {
// ".MathJax_MathML": {
// color: "red" // MathML is in red
// }
// }
//
styles: {}
},
//============================================================================
//
// These parameters control the contextual menus that are available on the
// mathematics within the page (provided the showMathMenu value is true above).
//
MathMenu: {
//
// This is the hover delay for the display of submenus in the
// contextual menu. When the mouse is still over a submenu label for
// this long, the menu will appear. (The menu also will appear if you
// click on the label.) It is in milliseconds.
//
delay: 400,
//
// This is the URL for the MathJax Help menu item.
//
helpURL: "http://www.mathjax.org/help/user/",
//
// These control whether the "Math Renderer", "Font Preferences",
// and "Contextual Menu" submenus will be displayed or not.
//
showRenderer: true,
showFontMenu: false,
showContext: false,
//
// These are the settings for the Show Source window. The initial
// width and height will be reset after the source is shown in an
// attempt to make the window fit the output better.
//
windowSettings: {
status: "no", toolbar: "no", locationbar: "no", menubar: "no",
directories: "no", personalbar: "no", resizable: "yes", scrollbars: "yes",
width: 100, height: 50
},
//
// This allows you to change the CSS that controls the menu
// appearance. See the extensions/MathMenu.js file for details
// of the default settings.
//
styles: {}
},
//============================================================================
//
// These parameters control the MMLorHTML configuration file.
// NOTE: if you add MMLorHTML.js to the config array above,
// you must REMOVE the output jax from the jax array.
//
MMLorHTML: {
//
// The output jax that is to be preferred when both are possible
// (set to "MML" for native MathML, "HTML" for MathJax's HTML-CSS output jax).
//
prefer: {
MSIE: "MML",
Firefox: "MML",
Opera: "HTML",
other: "HTML"
}
}
});
MathJax.Ajax.loadComplete("[MathJax]/config/MathJax.js");

590
math-scribble/MathJax/config/MathJax.js~ vendored Normal file
View File

@ -0,0 +1,590 @@
/*************************************************************
*
* MathJax/config/MathJax.js
*
* This configuration file is loaded when there is no explicit
* configuration script in the <script> tag that loads MathJax.js
*
* Use it to customize the MathJax settings. See comments below.
*
* ---------------------------------------------------------------------
*
* Copyright (c) 2009-10 Design Science, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
MathJax.Hub.Config({
//
// A comma-separated list of configuration files to load
// when MathJax starts up. E.g., to define local macros, etc.
// The default directory is the MathJax/config directory.
//
// Example: config: ["local/local.js"],
// Example: config: ["local/local.js","MMLtoHTML.js"],
//
config: [],
//
// A comma-separated list of CSS stylesheet files to be loaded
// when MathJax starts up. The default directory is the
// MathJax/config directory.
//
// Example: styleSheets: ["MathJax.css"],
//
styleSheets: [],
//
// Styles to be defined dynamically at startup time.
//
// Example:
// styles: {
// ".MathJax .merror": {
// color: "blue",
// "background-color": "green"
// }
// },
//
styles: {},
//
// A comma-separated list of input and output jax to initialize at startup.
// Their main code is loaded only when they are actually used, so it is not
// inefficient to include jax that may not actually be used on the page. These
// are found in the MathJax/jax directory.
//
jax: ["input/TeX","output/HTML-CSS"],
//
// A comma-separated list of extensions to load at startup. The default
// directory is MathJax/extensions.
//
// Example: extensions: ["tex2jax.js","TeX/AMSmath.js","TeX/AMSsymbols.js"],
//
extensions: ["tex2jax.js"],
//
// Patterns to remove from before and after math script tags. If you are not
// using one of the preprocessors (e.g., tex2jax), you need to insert something
// extra into your HTML file in order to avoid a bug in Internet Explorer. IE
// removes spaces from the DOM that it thinks are redundent, and since a SCRIPT
// tag usually doesn't add content to the page, if there is a space before and after
// a MathJax SCRIPT tag, IE will remove the first space. When MathJax inserts
// the typeset mathematics, this means there will be no space before it and the
// preceeding text. In order to avoid this, you should include some "guard characters"
// before or after the math SCRIPT tag; define the patterns you want to use below.
// Note that these are used as regular expressions, so you will need to quote
// special characters. Furthermore, since they are javascript strings, you must
// quote javascript special characters as well. So to obtain a backslash, you must
// use \\ (doubled for javascript). For example, "\\[" is the pattern \[ in the
// regular expression. That means that if you want an actual backslash in your
// guard characters, you need to use "\\\\" in order to get \\ in the regular
// expression, and \ in the actual text. If both preJax and postJax are defined,
// both must be present in order to be removed.
//
// See also the preRemoveClass comments below.
//
// Example:
// preJax: "\\\\\\\\", // makes a double backslash the preJax text
// or
// preJax: "\\[\\[", // jax scripts must be enclosed in double brackets
// postJax: "\\]\\]",
//
preJax: null,
postJax: null,
//
// The CSS class for a math preview to be removed preceeding a MathJax
// SCRIPT tag. If the tag just before the MathJax SCRIPT tag is of this
// class, its contents are removed when MathJax processes the SCRIPT
// tag. This allows you to include a math preview in a form that will
// be displayed prior to MathJax performing its typesetting. It also
// avoids the Internet Explorer space-removal bug, and can be used in
// place of preJax and postJax if that is more convenient.
//
// For example
//
// <span class="MathJax_Preview">[math]</span><script type="math/tex">...</script>
//
// would display "[math]" in place of the math until MathJax is able to typeset it.
//
preRemoveClass: "MathJax_Preview",
//
// This value controls whether the "Processing Math: nn%" message are displayed
// in the lower left-hand corner. Set to "false" to prevent those messages (though
// file loading and other messages will still be shown).
//
showProcessingMessages: true,
//
// This value controls the verbosity of the messages in the lower left-hand corner.
// Set it to "none" to eliminate all messages, or set it to "simple" to show
// "Loading..." and "Processing..." rather than showing the full file name and the
// percentage of the mathematics processed.
//
messageStyle: "normal",
//
// These two parameters control the alignment and shifting of displayed equations.
// The first can be "left", "center", or "right", and determines the alignment of
// displayed equations. When the alignment is not "center", the second determines
// an indentation from the left or right side for the displayed equations.
//
displayAlign: "center",
displayIndent: "0em",
//
// Normally MathJax will perform its starup commands (loading of
// configuration, styles, jax, and so on) as soon as it can. If you
// expect to be doing additional configuration on the page, however, you
// may want to have it wait until the page's onload hander is called. If so,
// set this to "onload".
//
delayStartupUntil: "none",
//
// Normally MathJax will typeset the mathematics on the page as soon as
// the page is loaded. If you want to delay that process, in which case
// you will need to call MathJax.Hub.Typeset() yourself by hand, set
// this value to true.
//
skipStartupTypeset: false,
//============================================================================
//
// These parameters control the tex2jax preprocessor (when you have included
// "tex2jax.js" in the extensions list above).
//
tex2jax: {
//
// The Id of the element to be processed (defaults to full document)
//
element: null,
//
// The delimiters that surround in-line math expressions. The first in each
// pair is the initial delimiter and the second is the terminal delimiter.
// Comment out any that you don't want, but be sure there is no extra
// comma at the end of the last item in the list -- some browsers won't
// be able to handle that.
//
inlineMath: [
// ['$','$'], // uncomment this for standard TeX math delimiters
['\\(','\\)']
],
//
// The delimiters that surround displayed math expressions. The first in each
// pair is the initial delimiter and the second is the terminal delimiter.
// Comment out any that you don't want, but be sure there is no extra
// comma at the end of the last item in the list -- some browsers won't
// be able to handle that.
//
displayMath: [
['$$','$$'],
['\\[','\\]']
],
//
// This array lists the names of the tags whose contents should not be
// processed by tex2jax (other than to look for ignore/process classes
// as listed below). You can add to (or remove from) this list to prevent
// MathJax from processing mathematics in specific contexts.
//
skipTags: ["script","noscript","style","textarea","pre","code"],
//
// This is the class name used to mark elements whose contents should
// not be processed by tex2jax (other than to look for the
// processClass pattern below). Note that this is a regular
// expression, and so you need to be sure to quote any regexp special
// characters. The pattern is automatically preceeded by '(^| )(' and
// followed by ')( |$)', so your pattern will have to match full words
// in the class name. Assigning an element this class name will
// prevent `tex2jax` from processing its contents.
//
ignoreClass: "tex2jax_ignore",
//
// This is the class name used to mark elements whose contents SHOULD
// be processed by tex2jax. This is used to turn on processing within
// tags that have been marked as ignored or skipped above. Note that
// this is a regular expression, and so you need to be sure to quote
// any regexp special characters. The pattern is automatically
// preceeded by '(^| )(' and followed by ')( |$)', so your pattern
// will have to match full words in the class name. Use this to
// restart processing within an element that has been marked as
// ignored above.
//
processClass: "tex2jax_process",
//
// Set to "true" to allow \$ to produce a dollar without starting in-line
// math mode. If you uncomment the ['$','$'] line above, you should change
// this to true so that you can insert plain dollar signs into your documents
//
processEscapes: false,
//
// Controls whether tex2jax processes LaTeX environments outside of math
// mode. Set to "false" to prevent processing of environments except within
// math mode.
//
processEnvironments: true,
//
// Controls whether tex2jax inserts MathJax_Preview spans to make a
// preview available, and what preview to use, when it locates in-line
// and display mathetics on the page. The default is "TeX", which
// means use the TeX code as the preview (until it is processed by
// MathJax). Set to "none" to prevent the previews from being
// inserted (the math will simply disappear until it is typeset). Set
// to an array containing the description of an HTML snippet in order
// to use the same preview for all equations on the page (e.g., you
// could have it say "[math]" or load an image).
//
// E.g., preview: ["[math]"],
// or preview: [["img",{src: "http://myserver.com/images/mypic.jpg"}]]
//
preview: "TeX"
},
//============================================================================
//
// These parameters control the mml2jax preprocessor (when you have included
// "mml2jax.js" in the extensions list above).
//
mml2jax: {
//
// The Id of the element to be processed (defaults to full document)
//
element: null,
//
// Controls whether mml2jax inserts MathJax_Preview spans to make a
// preview available, and what preview to use, whrn it locates
// mathematics on the page. The default is "alttext", which means use
// the <math> tag's alttext attribute as the preview (until it is
// processed by MathJax), if the tag has one. Set to "none" to
// prevent the previews from being inserted (the math will simply
// disappear until it is typeset). Set to an array containing the
// description of an HTML snippet in order to use the same preview for
// all equations on the page (e.g., you could have it say "[math]" or
// load an image).
//
// E.g., preview: ["[math]"],
// or preview: [["img",{src: "http://myserver.com/images/mypic.jpg"}]]
//
preview: "alttext"
},
//============================================================================
//
// These parameters control the jsMath2jax preprocessor (when you have included
// "jsMath2jax.js" in the extensions list above).
//
jsMath2jax: {
//
// The Id of the element to be processed (defaults to full document)
//
element: null,
//
// Controls whether jsMath2jax inserts MathJax_Preview spans to make a
// preview available, and what preview to use, when it locates
// mathematics on the page. The default is "TeX", which means use the
// TeX code as the preview (until it is processed by MathJax). Set to
// "none" to prevent the previews from being inserted (the math will
// simply disappear until it is typeset). Set to an array containing
// the description of an HTML snippet in order to use the same preview
// for all equations on the page (e.g., you could have it say "[math]"
// or load an image).
//
// E.g., preview: ["[math]"],
// or preview: [["img",{src: "http://myserver.com/images/mypic.jpg"}]]
//
preview: "TeX"
},
//============================================================================
//
// These parameters control the TeX input jax.
//
TeX: {
//
// This specifies the side on which \tag{} macros will place the tags.
// Set to "left" to place on the left-hand side.
//
TagSide: "right",
//
// This is the amound of indentation (from right or left) for the tags.
//
TagIndent: ".8em",
//
// This is the width to use for the multline environment
//
MultLineWidth: "85%",
//
// List of macros to define. These are of the form
// name: value
// where 'value' is the replacement text for the macro \name.
// The 'value' can also be [value,n] where 'value' is the replacement
// text and 'n' is the number of parameters for the macro.
// Note that backslashes must be doubled in the replacement string.
//
// E.g.,
//
// Macros: {
// RR: '{\\bf R}',
// bold: ['{\\bf #1}', 1]
// }
//
Macros: {}
},
//============================================================================
//
// These parameters control the MathML inupt jax.
//
MathML: {
//
// This specifies whether to use TeX spacing or MathML spacing when the
// HTML-CSS output jax is used.
//
useMathMLspacing: false
},
//============================================================================
//
// These parameters control the HTML-CSS output jax.
//
"HTML-CSS": {
//
// This controls the global scaling of mathematics as compared to the
// surrounding text. Values between 100 and 133 are usually good choices.
//
scale: 100,
//
// This is a list of the fonts to look for on a user's computer in
// preference to using MathJax's web-based fonts. These must
// correspond to directories available in the jax/output/HTML-CSS/fonts
// directory, where MathJax stores data about the characters available
// in the fonts. Set this to ["TeX"], for example, to prevent the
// use of the STIX fonts, or set it to an empty list, [], if
// you want to force MathJax to use web-based or image fonts.
//
availableFonts: ["STIX","TeX"],
//
// This is the preferred font to use when more than one of those
// listed above is available.
//
preferredFont: "TeX",
//
// This is the web-based font to use when none of the fonts listed
// above are available on the user's computer. Note that currently
// only the TeX font is available in a web-based form. Set this to
//
// webFont: null,
//
// if you want to prevent the use of web-based fonts.
//
webFont: "TeX",
//
// This is the font to use for image fallback mode (when none of the
// fonts listed above are available and the browser doesn't support
// web-fonts via the @font-face CSS directive). Note that currently
// only the TeX font is available as an image font. Set this to
//
// imageFont: null,
//
// if you want to prevent the use of image fonts (e.g., you have not
// installed the image fonts on your server). In this case, only
// browsers that support web-based fonts will be able to view your pages
// without having the fonts installed on the client computer. The browsers
// that support web-based fonts include: IE6 and later, Chrome, Safari3.1
// and above, Firefox3.5 and later, and Opera10 and later. Note that
// Firefox3.0 is NOT on this list, so without image fonts, FF3.0 users
// will be required to to download and install either the STIX fonts or the
// MathJax TeX fonts.
//
imageFont: "TeX",
//
// This controls whether the MathJax contextual menu will be available
// on the mathematics in the page. If true, then right-clicking (on
// the PC) or control-clicking (on the Mac) will produce a MathJax
// menu that allows you to get the source of the mathematics in
// various formats, change the size of the mathematics relative to the
// surrounding text, and get information about MathJax.
//
// Set this to false to disable the menu. When true, the MathMenu
// items below configure the actions of the menu.
//
showMathMenu: true,
//
// This allows you to define or modify the styles used to display
// various math elements created by MathJax.
//
// Example:
// styles: {
// ".MathJax_Preview": {
// "font-size": "80%", // preview uses a smaller font
// color: "red" // and is in red
// }
// }
//
styles: {},
//
// Configuration for <maction> tooltips
// (see also the #MathJax_Tooltip CSS in MathJax/jax/output/HTML-CSS/config.js,
// which can be overriden using the styles values above).
//
tooltip: {
delayPost: 600, // milliseconds delay before tooltip is posted after mouseover
delayClear: 600, // milliseconds delay before tooltip is cleared after mouseout
offsetX: 10, offsetY: 5 // pixels to offset tooltip from mouse position
}
},
//============================================================================
//
// These parameters control the NativeMML output jax.
//
NativeMML: {
//
// This controls the global scaling of mathematics as compared to the
// surrounding text. Values between 100 and 133 are usually good choices.
//
scale: 100,
//
// This controls whether the MathJax contextual menu will be available
// on the mathematics in the page. If true, then right-clicking (on
// the PC) or control-clicking (on the Mac) will produce a MathJax
// menu that allows you to get the source of the mathematics in
// various formats, change the size of the mathematics relative to the
// surrounding text, and get information about MathJax.
//
// Set this to false to disable the menu. When true, the MathMenu
// items below configure the actions of the menu.
//
// There is a separate setting for MSIE, since the code to handle that
// is a bit delicate; if it turns out to have unexpected consequences,
// you can turn it off without turing off other browser support.
//
showMathMenu: true,
showMathMenuMSIE: true,
//
// This allows you to define or modify the styles used to display
// various math elements created by MathJax.
//
// Example:
// styles: {
// ".MathJax_MathML": {
// color: "red" // MathML is in red
// }
// }
//
styles: {}
},
//============================================================================
//
// These parameters control the contextual menus that are available on the
// mathematics within the page (provided the showMathMenu value is true above).
//
MathMenu: {
//
// This is the hover delay for the display of submenus in the
// contextual menu. When the mouse is still over a submenu label for
// this long, the menu will appear. (The menu also will appear if you
// click on the label.) It is in milliseconds.
//
delay: 400,
//
// This is the URL for the MathJax Help menu item.
//
helpURL: "http://www.mathjax.org/help/user/",
//
// These control whether the "Math Renderer", "Font Preferences",
// and "Contextual Menu" submenus will be displayed or not.
//
showRenderer: true,
showFontMenu: false,
showContext: false,
//
// These are the settings for the Show Source window. The initial
// width and height will be reset after the source is shown in an
// attempt to make the window fit the output better.
//
windowSettings: {
status: "no", toolbar: "no", locationbar: "no", menubar: "no",
directories: "no", personalbar: "no", resizable: "yes", scrollbars: "yes",
width: 100, height: 50
},
//
// This allows you to change the CSS that controls the menu
// appearance. See the extensions/MathMenu.js file for details
// of the default settings.
//
styles: {}
},
//============================================================================
//
// These parameters control the MMLorHTML configuration file.
// NOTE: if you add MMLorHTML.js to the config array above,
// you must REMOVE the output jax from the jax array.
//
MMLorHTML: {
//
// The output jax that is to be preferred when both are possible
// (set to "MML" for native MathML, "HTML" for MathJax's HTML-CSS output jax).
//
prefer: {
MSIE: "MML",
Firefox: "MML",
Opera: "HTML",
other: "HTML"
}
}
});
MathJax.Ajax.loadComplete("[MathJax]/config/MathJax.js");

View File

@ -0,0 +1,37 @@
/*************************************************************
*
* MathJax/config/local/local.js
*
* Include changes and configuration local to your installation
* in this file. For example, common macros can be defined here
* (see below). To use this file, add "local/local.js" to the
* config array in MathJax.js or your MathJax.Hub.Config() call.
*
* ---------------------------------------------------------------------
*
* Copyright (c) 2009 Design Science, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
MathJax.Hub.Register.StartupHook("TeX Jax Ready",function () {
var TEX = MathJax.InputJax.TeX;
// place macros here. E.g.:
// TEX.Macro("R","{\\bf R}");
// TEX.Macro("op","\\mathop{\\rm #1}",1); // a macro with 1 parameter
});
MathJax.Ajax.loadComplete("[MathJax]/config/local/local.js");

View File

@ -0,0 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: fedf9ba9a5b2ef65b82b1fa1eea24e52
tags: fbb0d17656682115ca4d033fb2f83ba1

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More