├── hw ├── 10 │ ├── code │ │ ├── rat.onebody.1day.auto.txt │ │ ├── tests │ │ │ ├── rat.onebody.1day.auto.txt │ │ │ ├── rat.twobody.1day.auto.txt │ │ │ ├── rat.onebody.2weeks.auto.txt │ │ │ ├── rat.twobody.2day.auto.txt │ │ │ ├── rat.system.1day.auto.txt │ │ │ └── rat.twobody.3day.auto.txt │ │ ├── real.onebody.1day.auto.txt │ │ ├── real.twobody.1day.auto.txt │ │ ├── rat.twobody.1day.auto.txt │ │ ├── real.twobody.2day.auto.txt │ │ ├── sources.cm │ │ ├── rat.onebody.2weeks.auto.txt │ │ ├── tseq.sig │ │ ├── real.twobody.3day.auto.txt │ │ ├── lib │ │ │ ├── planeargs.sig │ │ │ ├── bhargs.sig │ │ │ ├── mechanics.sig │ │ │ ├── realplaneargs.sml │ │ │ ├── bh.sig │ │ │ ├── makescalar.sml │ │ │ ├── scalar.sig │ │ │ ├── bbox.sig │ │ │ ├── space.sig │ │ │ ├── simulation.sml │ │ │ ├── solars.sml │ │ │ ├── ratplaneargs.sml │ │ │ ├── mechanics.sml │ │ │ ├── makeplane.sml │ │ │ └── transcripts.sml │ │ ├── real.twobody.4day.auto.txt │ │ ├── real.twobody.5day.auto.txt │ │ ├── real.twobody.6day.auto.txt │ │ ├── comparetranscripts.sh │ │ ├── real.onebody.2weeks.auto.txt │ │ ├── real.system.1day.auto.txt │ │ ├── support.cm │ │ ├── real.system.2day.auto.txt │ │ ├── rat.twobody.2day.auto.txt │ │ ├── naiveNBody.sml │ │ ├── rat.system.1day.auto.txt │ │ ├── sizeseq.sml │ │ ├── shrubseq.sml │ │ └── rat.twobody.3day.auto.txt │ ├── hw10-handout.pdf │ ├── config.py │ ├── Makefile │ ├── IN_CASE_OF_EMERGENCY │ └── bobbfile.py ├── 11 │ ├── hw11-handout.pdf │ ├── config.py │ ├── code │ │ ├── player.sig │ │ ├── printer.sig │ │ ├── graphseq.sig │ │ ├── sources.cm │ │ ├── estimate.sml │ │ ├── map.sig │ │ ├── estimate.sig │ │ ├── printer.sml │ │ ├── game.sig │ │ ├── sequtils.sml │ │ ├── humanplayer.sml │ │ ├── runriskless.sml │ │ ├── referee.sml │ │ ├── minimax.sml │ │ └── graphseq.sml │ ├── Makefile │ ├── IN_CASE_OF_EMERGENCY │ └── bobbfile.py ├── 12 │ ├── hw12-handout.pdf │ ├── config.py │ ├── code │ │ ├── fibo.sig │ │ ├── countingdict.sig │ │ ├── dict.sig │ │ ├── sources.cm │ │ ├── lazy.sig │ │ ├── fib.sml │ │ ├── memo.sig │ │ ├── lazylist.sig │ │ ├── poormemoizer.sml │ │ ├── memo_reference.sml │ │ ├── lazylist.sml │ │ ├── treedict.sml │ │ ├── countingdict.sml │ │ ├── memo.sml │ │ └── lazy.sml │ ├── Makefile │ ├── IN_CASE_OF_EMERGENCY │ └── bobbfile.py ├── 08 │ ├── code │ │ ├── typedef.sig │ │ ├── exceptions.sig │ │ ├── treefind.sig │ │ ├── sources.cm │ │ ├── stack.sig │ │ ├── dict.sig │ │ ├── order.sml │ │ ├── queues.sml │ │ ├── dictclient.sml │ │ ├── treefind.sml │ │ ├── exceptions.sml │ │ └── stack.sml │ ├── hw08-handout.pdf │ ├── solutions │ │ ├── hw08-sol.pdf │ │ └── code │ │ │ ├── sources.cm │ │ │ ├── exceptions.sml │ │ │ ├── treefind.sml │ │ │ ├── fundict.sml │ │ │ └── stack.sml │ └── Makefile ├── 01 │ ├── hw01-handout.pdf │ ├── solutions │ │ ├── hw01-sol.pdf │ │ └── code │ │ │ └── hw01-sol.sml │ ├── Makefile │ └── code │ │ └── hw01.sml ├── 02 │ ├── hw02-handout.pdf │ ├── solutions │ │ ├── hw02-sol.pdf │ │ └── code │ │ │ └── hw02-sol.sml │ ├── Makefile │ └── code │ │ └── hw02-proof-templates.tex ├── 03 │ ├── hw03-handout.pdf │ ├── solutions │ │ └── hw03-sol.pdf │ ├── Makefile │ └── code │ │ └── lib.sml ├── 04 │ ├── hw04-handout.pdf │ ├── solutions │ │ └── hw04-sol.pdf │ └── Makefile ├── 05 │ ├── hw05-handout.pdf │ ├── solutions │ │ └── hw05-sol.pdf │ ├── Makefile │ └── code │ │ └── lib.sml ├── 06 │ ├── hw06-handout.pdf │ ├── solutions │ │ └── hw06-sol.pdf │ └── Makefile ├── 07 │ ├── hw07-handout.pdf │ ├── solutions │ │ ├── hw07-sol.pdf │ │ └── code │ │ │ └── hw07-sol.sml │ ├── Makefile │ └── code │ │ └── hw07.sml └── 09 │ ├── hw09-handout.pdf │ ├── solutions │ ├── hw09-sol.pdf │ └── code │ │ └── sources.cm │ ├── code │ ├── marshalpair.sig │ ├── marshal.sig │ ├── sources.cm │ ├── support.cm │ ├── util.sig │ └── util.sml │ └── Makefile ├── src ├── sequence │ ├── seq.sml │ ├── vectorsequence.sml │ ├── sources.cm │ ├── sequencecore-sig.sml │ ├── derivesequence.sml │ ├── sequence-sig.sml │ └── vectorcore.sml └── ordered │ ├── ordered.sig │ ├── twoorders.sig │ ├── string.sml │ ├── sources.cm │ ├── int.sml │ └── utils.sml ├── lab ├── 10 │ ├── lab10-handout.pdf │ ├── code │ │ ├── pairset.sml │ │ ├── equal.sig │ │ ├── sources.cm │ │ ├── setofsets.sml │ │ ├── rbtree.sml │ │ ├── dictset.sml │ │ ├── set.sig │ │ ├── dict.sig │ │ └── dict.sml │ └── solutions │ │ ├── sources.cm │ │ ├── setofsets.sml │ │ ├── pairset.sml │ │ ├── dictset.sml │ │ └── rbtree.sml ├── 11 │ ├── lab11-handout.pdf │ └── code │ │ └── sources.cm ├── 12 │ └── lab12-handout.pdf ├── 13 │ ├── lab13-handout.pdf │ └── code │ │ └── lab13.sml ├── 14 │ └── lab14-handout.pdf ├── 08 │ ├── treefreq.pdf │ ├── lab08-handout.pdf │ └── treefreq-sol.pdf ├── 05 │ ├── lab05-notes.pdf │ ├── lab05-handout.pdf │ ├── solutions │ │ ├── lab05-sol.pdf │ │ └── lab05-sol.sml │ └── code │ │ └── lab05.sml ├── 01 │ ├── lab01-handout.pdf │ ├── solutions │ │ ├── lab01-sol.pdf │ │ └── code │ │ │ └── lab01-sol.sml │ └── code │ │ └── lab01.sml ├── 02 │ ├── lab02-handout.pdf │ ├── solutions │ │ └── lab02-sol.pdf │ └── code │ │ └── lab02.sml ├── 03 │ ├── lab03-handout.pdf │ ├── solutions │ │ └── lab03-sol.pdf │ └── code │ │ └── lab03.sml ├── 04 │ ├── lab04-handout.pdf │ ├── solutions │ │ └── lab04-sol.pdf │ └── code │ │ └── lab04.sml ├── 06 │ ├── lab06-handout.pdf │ └── solutions │ │ └── lab06-sol.pdf ├── 07 │ ├── lab07-handout.pdf │ ├── solutions │ │ └── lab07-sol.pdf │ └── code │ │ └── lab07.sml └── 09 │ ├── lab09-handout.pdf │ ├── solutions │ ├── lab09-sol.pdf │ └── code │ │ ├── sources.cm │ │ ├── intset.sig │ │ ├── FindException.sml │ │ ├── ListSets.sml │ │ └── TreeSets.sml │ └── code │ ├── sources.cm │ ├── FindException.sml │ ├── intset.sig │ ├── TreeSets.sml │ └── ListSets.sml ├── handouts ├── BarnesHut.pdf ├── midterm-practice.pdf └── sequencereference.pdf └── README /hw/10/code/rat.onebody.1day.auto.txt: -------------------------------------------------------------------------------- 1 | 2 | (0, 0) 3 | (0, 0) 4 | -------------------------------------------------------------------------------- /src/sequence/seq.sml: -------------------------------------------------------------------------------- 1 | structure Seq : SEQUENCE = VectorSeq 2 | -------------------------------------------------------------------------------- /hw/08/code/typedef.sig: -------------------------------------------------------------------------------- 1 | signature TYPEDEF = 2 | sig 3 | type t 4 | end -------------------------------------------------------------------------------- /hw/10/code/tests/rat.onebody.1day.auto.txt: -------------------------------------------------------------------------------- 1 | 2 | (0, 0) 3 | (0, 0) 4 | -------------------------------------------------------------------------------- /hw/10/code/real.onebody.1day.auto.txt: -------------------------------------------------------------------------------- 1 | 2 | (0.0000E0, 0.0000E0) 3 | (0.0000E0, 0.0000E0) 4 | -------------------------------------------------------------------------------- /lab/08/treefreq.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/08/treefreq.pdf -------------------------------------------------------------------------------- /handouts/BarnesHut.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/handouts/BarnesHut.pdf -------------------------------------------------------------------------------- /hw/01/hw01-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/hw/01/hw01-handout.pdf -------------------------------------------------------------------------------- /hw/02/hw02-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/hw/02/hw02-handout.pdf -------------------------------------------------------------------------------- /hw/03/hw03-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/hw/03/hw03-handout.pdf -------------------------------------------------------------------------------- /hw/04/hw04-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/hw/04/hw04-handout.pdf -------------------------------------------------------------------------------- /hw/05/hw05-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/hw/05/hw05-handout.pdf -------------------------------------------------------------------------------- /hw/06/hw06-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/hw/06/hw06-handout.pdf -------------------------------------------------------------------------------- /hw/07/hw07-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/hw/07/hw07-handout.pdf -------------------------------------------------------------------------------- /hw/08/hw08-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/hw/08/hw08-handout.pdf -------------------------------------------------------------------------------- /hw/09/hw09-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/hw/09/hw09-handout.pdf -------------------------------------------------------------------------------- /hw/10/hw10-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/hw/10/hw10-handout.pdf -------------------------------------------------------------------------------- /hw/11/hw11-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/hw/11/hw11-handout.pdf -------------------------------------------------------------------------------- /hw/12/hw12-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/hw/12/hw12-handout.pdf -------------------------------------------------------------------------------- /lab/05/lab05-notes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/05/lab05-notes.pdf -------------------------------------------------------------------------------- /lab/01/lab01-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/01/lab01-handout.pdf -------------------------------------------------------------------------------- /lab/02/lab02-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/02/lab02-handout.pdf -------------------------------------------------------------------------------- /lab/03/lab03-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/03/lab03-handout.pdf -------------------------------------------------------------------------------- /lab/04/lab04-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/04/lab04-handout.pdf -------------------------------------------------------------------------------- /lab/05/lab05-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/05/lab05-handout.pdf -------------------------------------------------------------------------------- /lab/06/lab06-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/06/lab06-handout.pdf -------------------------------------------------------------------------------- /lab/07/lab07-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/07/lab07-handout.pdf -------------------------------------------------------------------------------- /lab/08/lab08-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/08/lab08-handout.pdf -------------------------------------------------------------------------------- /lab/08/treefreq-sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/08/treefreq-sol.pdf -------------------------------------------------------------------------------- /lab/09/lab09-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/09/lab09-handout.pdf -------------------------------------------------------------------------------- /lab/10/lab10-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/10/lab10-handout.pdf -------------------------------------------------------------------------------- /lab/11/lab11-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/11/lab11-handout.pdf -------------------------------------------------------------------------------- /lab/12/lab12-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/12/lab12-handout.pdf -------------------------------------------------------------------------------- /lab/13/lab13-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/13/lab13-handout.pdf -------------------------------------------------------------------------------- /lab/14/lab14-handout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/14/lab14-handout.pdf -------------------------------------------------------------------------------- /handouts/midterm-practice.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/handouts/midterm-practice.pdf -------------------------------------------------------------------------------- /handouts/sequencereference.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/handouts/sequencereference.pdf -------------------------------------------------------------------------------- /hw/01/solutions/hw01-sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/hw/01/solutions/hw01-sol.pdf -------------------------------------------------------------------------------- /hw/02/solutions/hw02-sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/hw/02/solutions/hw02-sol.pdf -------------------------------------------------------------------------------- /hw/03/solutions/hw03-sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/hw/03/solutions/hw03-sol.pdf -------------------------------------------------------------------------------- /hw/04/solutions/hw04-sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/hw/04/solutions/hw04-sol.pdf -------------------------------------------------------------------------------- /hw/05/solutions/hw05-sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/hw/05/solutions/hw05-sol.pdf -------------------------------------------------------------------------------- /hw/06/solutions/hw06-sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/hw/06/solutions/hw06-sol.pdf -------------------------------------------------------------------------------- /hw/07/solutions/hw07-sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/hw/07/solutions/hw07-sol.pdf -------------------------------------------------------------------------------- /hw/08/solutions/hw08-sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/hw/08/solutions/hw08-sol.pdf -------------------------------------------------------------------------------- /hw/09/solutions/hw09-sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/hw/09/solutions/hw09-sol.pdf -------------------------------------------------------------------------------- /lab/01/solutions/lab01-sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/01/solutions/lab01-sol.pdf -------------------------------------------------------------------------------- /lab/02/solutions/lab02-sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/02/solutions/lab02-sol.pdf -------------------------------------------------------------------------------- /lab/03/solutions/lab03-sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/03/solutions/lab03-sol.pdf -------------------------------------------------------------------------------- /lab/04/solutions/lab04-sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/04/solutions/lab04-sol.pdf -------------------------------------------------------------------------------- /lab/05/solutions/lab05-sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/05/solutions/lab05-sol.pdf -------------------------------------------------------------------------------- /lab/06/solutions/lab06-sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/06/solutions/lab06-sol.pdf -------------------------------------------------------------------------------- /lab/07/solutions/lab07-sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/07/solutions/lab07-sol.pdf -------------------------------------------------------------------------------- /lab/09/solutions/lab09-sol.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengguan/15150-1/HEAD/lab/09/solutions/lab09-sol.pdf -------------------------------------------------------------------------------- /src/ordered/ordered.sig: -------------------------------------------------------------------------------- 1 | signature ORDERED = 2 | sig 3 | type t 4 | val compare : t * t -> order 5 | end 6 | -------------------------------------------------------------------------------- /hw/12/config.py: -------------------------------------------------------------------------------- 1 | handin_files = ['code/countingdict.sml', 'code/lazy.sml', 'code/memo.sml'] 2 | lab_name = 'hw12' 3 | -------------------------------------------------------------------------------- /hw/09/code/marshalpair.sig: -------------------------------------------------------------------------------- 1 | signature MARSHALPAIR = 2 | sig 3 | structure M1 : MARSHAL 4 | structure M2 : MARSHAL 5 | end 6 | -------------------------------------------------------------------------------- /lab/11/code/sources.cm: -------------------------------------------------------------------------------- 1 | group is 2 | $/basis.cm 3 | 4 | ../../../src/sequence/sources.cm 5 | 6 | lab11.sml 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/ordered/twoorders.sig: -------------------------------------------------------------------------------- 1 | signature TWOORDERS = 2 | sig 3 | structure O1 : ORDERED 4 | structure O2 : ORDERED 5 | end 6 | -------------------------------------------------------------------------------- /hw/10/code/real.twobody.1day.auto.txt: -------------------------------------------------------------------------------- 1 | 2 | (0.0000E0, 0.0000E0),(0.0000E0, ~1.4960E11) 3 | (0.0000E0, ~1.3299E4),(~2.5730E10, ~1.4517E11) 4 | -------------------------------------------------------------------------------- /hw/11/config.py: -------------------------------------------------------------------------------- 1 | handin_files = ['code/graphseq.sml','code/riskless.sml', 'code/alphabeta.sml', 'code/jamboree.sml'] 2 | lab_name = 'hw11' 3 | -------------------------------------------------------------------------------- /hw/01/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for 15-150 s13 hw01 2 | 3 | all: 4 | tar -cf hw01.tar hw01.pdf code/hw01.sml 5 | 6 | clean: 7 | rm -rf hw01.tar 8 | -------------------------------------------------------------------------------- /hw/02/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for 15-150 s13 hw02 2 | 3 | all: 4 | tar -cf hw02.tar hw02.pdf code/hw02.sml 5 | 6 | clean: 7 | rm -rf hw02.tar 8 | -------------------------------------------------------------------------------- /hw/03/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for 15-150 s13 hw03 2 | 3 | all: 4 | tar -cf hw03.tar hw03.pdf code/hw03.sml 5 | 6 | clean: 7 | rm -rf hw03.tar 8 | -------------------------------------------------------------------------------- /hw/04/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for 15-150 s13 hw03 2 | 3 | all: 4 | tar -cf hw04.tar hw04.pdf code/hw04.sml 5 | 6 | clean: 7 | rm -rf hw04.tar 8 | -------------------------------------------------------------------------------- /hw/05/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for 15-150 s13 hw05 2 | 3 | all: 4 | tar -cf hw05.tar hw05.pdf code/hw05.sml 5 | 6 | clean: 7 | rm -rf hw05.tar 8 | -------------------------------------------------------------------------------- /hw/06/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for 15-150 s13 hw06 2 | 3 | all: 4 | tar -cf hw06.tar hw06.pdf code/hw06.sml 5 | 6 | clean: 7 | rm -rf hw06.tar 8 | -------------------------------------------------------------------------------- /hw/07/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for 15-150 s13 hw07 2 | 3 | all: 4 | tar -cf hw07.tar hw07.pdf code/hw07.sml 5 | 6 | clean: 7 | rm -rf hw07.tar 8 | -------------------------------------------------------------------------------- /hw/10/code/rat.twobody.1day.auto.txt: -------------------------------------------------------------------------------- 1 | 2 | (0, 0),(0, ~149600000000) 3 | (0, ~7266212549208/546390625),(~25729920000, ~25382636804426368/174845) 4 | -------------------------------------------------------------------------------- /hw/10/code/tests/rat.twobody.1day.auto.txt: -------------------------------------------------------------------------------- 1 | 2 | (0, 0),(0, ~149600000000) 3 | (0, ~7266212549208/546390625),(~25729920000, ~25382636804426368/174845) 4 | -------------------------------------------------------------------------------- /hw/10/config.py: -------------------------------------------------------------------------------- 1 | handin_files = ['code/barnes-hut.sml', 'code/tester.sml', 'code/sizeseq.sml', 'code/shrubseq.sml', 'hw10.pdf'] 2 | lab_name = 'hw10' 3 | -------------------------------------------------------------------------------- /hw/12/code/fibo.sig: -------------------------------------------------------------------------------- 1 | signature FIBO = 2 | sig 3 | (* on input n, computes the nth Fibonacci number *) 4 | val fib : IntInf.int -> IntInf.int 5 | end 6 | -------------------------------------------------------------------------------- /src/ordered/string.sml: -------------------------------------------------------------------------------- 1 | structure StringOrder : ORDERED = 2 | struct 3 | type t = string 4 | 5 | val compare : t * t -> order = String.compare 6 | end 7 | -------------------------------------------------------------------------------- /lab/10/code/pairset.sml: -------------------------------------------------------------------------------- 1 | functor PairSet (PE : PAIR_OF_EQUAL) : SET = 2 | struct 3 | 4 | (* Implement the set cartesian product here *) 5 | 6 | end 7 | 8 | -------------------------------------------------------------------------------- /src/ordered/sources.cm: -------------------------------------------------------------------------------- 1 | group is 2 | $/basis.cm 3 | ordered.sig 4 | int.sml 5 | string.sml 6 | twoorders.sig 7 | utils.sml 8 | -------------------------------------------------------------------------------- /hw/08/code/exceptions.sig: -------------------------------------------------------------------------------- 1 | signature FACTORIZE = 2 | sig 3 | exception Prime 4 | val next_divisor : int * int -> int 5 | val factorizer : int -> int list 6 | end -------------------------------------------------------------------------------- /hw/09/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for 15-150 f13 hw09 2 | 3 | all: 4 | tar -cf hw09.tar hw09.pdf code/marshal.sml code/sequences.sml 5 | 6 | clean: 7 | rm -rf hw09.tar 8 | -------------------------------------------------------------------------------- /hw/11/code/player.sig: -------------------------------------------------------------------------------- 1 | signature PLAYER = 2 | sig 3 | structure Game : GAME 4 | 5 | (* assumes game is In_play *) 6 | val next_move : Game.state -> Game.move 7 | end 8 | 9 | -------------------------------------------------------------------------------- /hw/10/code/real.twobody.2day.auto.txt: -------------------------------------------------------------------------------- 1 | 2 | (0.0000E0, 0.0000E0),(0.0000E0, ~1.4960E11) 3 | (0.0000E0, ~1.3299E4),(~2.5730E10, ~1.4517E11) 4 | (~2.3895E3, ~4.0079E4),(~5.0664E10, ~1.3626E11) 5 | -------------------------------------------------------------------------------- /hw/09/solutions/code/sources.cm: -------------------------------------------------------------------------------- 1 | group is 2 | $/basis.cm 3 | 4 | ../../../../src/sequence/sources.cm 5 | 6 | ../../code/sources.cm 7 | sequences.sml 8 | marshal.sml 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /hw/10/code/sources.cm: -------------------------------------------------------------------------------- 1 | group is 2 | $/basis.cm 3 | 4 | tseq.sig 5 | shrubseq.sml 6 | sizeseq.sml 7 | 8 | support.cm 9 | barnes-hut.sml 10 | tester.sml 11 | 12 | -------------------------------------------------------------------------------- /src/sequence/vectorsequence.sml: -------------------------------------------------------------------------------- 1 | structure VectorSeq : SEQUENCE = struct 2 | structure VS = DeriveSequence (VectorCore) 3 | open VS 4 | 5 | (* TODO: optimized versions of split, take, and drop. *) 6 | end 7 | -------------------------------------------------------------------------------- /hw/08/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for 15-150 s13 hw08 2 | 3 | all: 4 | tar -cf hw08.tar hw08.pdf code/exceptions.sml code/fundict.sml code/stack.sml code/treedict.sml code/treefind.sml 5 | 6 | clean: 7 | rm -rf hw08.tar 8 | -------------------------------------------------------------------------------- /hw/10/code/rat.onebody.2weeks.auto.txt: -------------------------------------------------------------------------------- 1 | 2 | (0, 0) 3 | (0, 0) 4 | (0, 0) 5 | (0, 0) 6 | (0, 0) 7 | (0, 0) 8 | (0, 0) 9 | (0, 0) 10 | (0, 0) 11 | (0, 0) 12 | (0, 0) 13 | (0, 0) 14 | (0, 0) 15 | (0, 0) 16 | (0, 0) 17 | -------------------------------------------------------------------------------- /hw/10/code/tseq.sig: -------------------------------------------------------------------------------- 1 | signature TSEQ = 2 | sig 3 | type 'a seq 4 | exception Range 5 | val length : 'a seq -> int 6 | val nth : int -> 'a seq -> 'a 7 | val tabulate : (int -> 'a) -> int -> 'a seq 8 | end 9 | -------------------------------------------------------------------------------- /hw/08/code/treefind.sig: -------------------------------------------------------------------------------- 1 | signature TREEFIND = 2 | sig 3 | datatype 'a ntree = Empty 4 | | Node of 'a * 'a ntree list 5 | type 'a tree = 'a ntree 6 | val find : ('a -> bool) -> 'a tree -> 'a tree 7 | end 8 | -------------------------------------------------------------------------------- /hw/10/code/tests/rat.onebody.2weeks.auto.txt: -------------------------------------------------------------------------------- 1 | 2 | (0, 0) 3 | (0, 0) 4 | (0, 0) 5 | (0, 0) 6 | (0, 0) 7 | (0, 0) 8 | (0, 0) 9 | (0, 0) 10 | (0, 0) 11 | (0, 0) 12 | (0, 0) 13 | (0, 0) 14 | (0, 0) 15 | (0, 0) 16 | (0, 0) 17 | -------------------------------------------------------------------------------- /hw/09/code/marshal.sig: -------------------------------------------------------------------------------- 1 | signature MARSHAL = 2 | sig 3 | type t 4 | 5 | (* invariant: For all v, s: read (write v ^ s) == SOME (v , s) *) 6 | val write : t -> string 7 | val read : string -> (t * string) option 8 | end 9 | -------------------------------------------------------------------------------- /hw/09/code/sources.cm: -------------------------------------------------------------------------------- 1 | group is 2 | $/basis.cm 3 | 4 | ../../../src/sequence/sources.cm 5 | 6 | util.sig 7 | util.sml 8 | marshal.sig 9 | marshalpair.sig 10 | sequences.sml 11 | marshal.sml 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/sequence/sources.cm: -------------------------------------------------------------------------------- 1 | group is 2 | $/basis.cm 3 | 4 | sequence-sig.sml 5 | sequencecore-sig.sml 6 | derivesequence.sml 7 | 8 | vectorcore.sml 9 | vectorsequence.sml 10 | 11 | seq.sml -------------------------------------------------------------------------------- /hw/10/code/real.twobody.3day.auto.txt: -------------------------------------------------------------------------------- 1 | 2 | (0.0000E0, 0.0000E0),(0.0000E0, ~1.4960E11) 3 | (0.0000E0, ~1.3299E4),(~2.5730E10, ~1.4517E11) 4 | (~2.3895E3, ~4.0079E4),(~5.0664E10, ~1.3626E11) 5 | (~9.6875E3, ~8.0060E4),(~7.3964E10, ~1.2294E11) 6 | -------------------------------------------------------------------------------- /hw/12/code/countingdict.sig: -------------------------------------------------------------------------------- 1 | signature COUNTING_DICT = 2 | sig 3 | structure Key : ORDERED 4 | type 'a dict 5 | 6 | val build : (Key.t * 'a) list -> 'a dict 7 | val lookup : 'a dict -> Key.t -> 'a option 8 | val hits : 'a dict -> Key.t -> int 9 | end 10 | -------------------------------------------------------------------------------- /hw/10/code/lib/planeargs.sig: -------------------------------------------------------------------------------- 1 | signature PLANEARGS = 2 | sig 3 | structure Seq : SEQUENCE 4 | structure Scalar : SCALAR 5 | val distance : (Scalar.scalar * Scalar.scalar) 6 | -> (Scalar.scalar * Scalar.scalar) 7 | -> Scalar.scalar 8 | end 9 | -------------------------------------------------------------------------------- /hw/11/code/printer.sig: -------------------------------------------------------------------------------- 1 | signature Printer = 2 | sig 3 | val nDups : char -> int -> string 4 | 5 | val pad : int -> string -> string 6 | 7 | val padAll : string Seq.seq -> string Seq.seq 8 | 9 | val labelAll : string Seq.seq -> string Seq.seq 10 | end 11 | -------------------------------------------------------------------------------- /hw/09/code/support.cm: -------------------------------------------------------------------------------- 1 | Group is 2 | $/basis.cm 3 | 4 | ../../../../src/sequence/sources.cm 5 | 6 | (* Question 4 *) 7 | order.sml 8 | dict.sig 9 | 10 | (* Question 5 *) 11 | util.sig 12 | util.sml 13 | serializable.sig 14 | -------------------------------------------------------------------------------- /hw/10/code/real.twobody.4day.auto.txt: -------------------------------------------------------------------------------- 1 | 2 | (0.0000E0, 0.0000E0),(0.0000E0, ~1.4960E11) 3 | (0.0000E0, ~1.3299E4),(~2.5730E10, ~1.4517E11) 4 | (~2.3895E3, ~4.0079E4),(~5.0664E10, ~1.3626E11) 5 | (~9.6875E3, ~8.0060E4),(~7.3964E10, ~1.2294E11) 6 | (~2.4439E4, ~1.3243E5),(~9.4783E10, ~1.0551E11) 7 | -------------------------------------------------------------------------------- /hw/12/code/dict.sig: -------------------------------------------------------------------------------- 1 | signature DICT = 2 | sig 3 | structure Key : ORDERED 4 | type 'v dict 5 | 6 | val empty : 'v dict 7 | val insert : 'v dict -> (Key.t * 'v) -> 'v dict 8 | val lookup : 'v dict -> Key.t -> 'v option 9 | val remove : 'v dict -> Key.t -> 'v dict 10 | end 11 | -------------------------------------------------------------------------------- /hw/12/code/sources.cm: -------------------------------------------------------------------------------- 1 | Group is 2 | $/basis.cm 3 | 4 | ../../../src/ordered/sources.cm 5 | dict.sig 6 | treedict.sml 7 | 8 | countingdict.sig 9 | countingdict.sml 10 | 11 | lazylist.sig 12 | lazylist.sml 13 | lazy.sig 14 | lazy.sml 15 | 16 | fibo.sig 17 | memo.sig 18 | memo.sml 19 | memo_reference.sml 20 | -------------------------------------------------------------------------------- /lab/10/code/equal.sig: -------------------------------------------------------------------------------- 1 | signature EQUAL = 2 | sig 3 | type t (* type of element *) 4 | 5 | (* returns true if t1 is equal to t2 and false otherwise *) 6 | val equal : t * t -> bool 7 | end 8 | 9 | signature PAIR_OF_EQUAL = 10 | sig 11 | structure E1 : EQUAL 12 | structure E2 : EQUAL 13 | end 14 | -------------------------------------------------------------------------------- /lab/10/code/sources.cm: -------------------------------------------------------------------------------- 1 | (* Note: You should add the names of the files that you create for this lab below *) 2 | 3 | Group is 4 | $/basis.cm 5 | 6 | set.sig 7 | equal.sig 8 | 9 | dictset.sml 10 | (* setofsets.sml *) 11 | (* pairset.sml *) 12 | (* rbtree.sml *) 13 | 14 | dict.sig 15 | dict.sml 16 | -------------------------------------------------------------------------------- /lab/10/solutions/sources.cm: -------------------------------------------------------------------------------- 1 | (* Note: You should add the names of the files that you create for this lab below *) 2 | 3 | Group is 4 | $/basis.cm 5 | 6 | ../code/set.sig 7 | ../code/equal.sig 8 | 9 | dictset.sml 10 | setofsets.sml 11 | pairset.sml 12 | rbtree.sml 13 | ../code/dict.sig 14 | ../code/dict.sml 15 | -------------------------------------------------------------------------------- /hw/12/code/lazy.sig: -------------------------------------------------------------------------------- 1 | signature LAZY = 2 | sig 3 | 4 | datatype lazylist = datatype LazyList.lazylist 5 | 6 | val lazy_merge : ('a * 'a -> order) -> 'a lazylist -> 'a lazylist -> 'a lazylist 7 | val combine : ('a * 'a -> order) -> 'a lazylist lazylist -> 'a lazylist 8 | val pairs : (int * int) lazylist 9 | 10 | end -------------------------------------------------------------------------------- /src/ordered/int.sml: -------------------------------------------------------------------------------- 1 | structure IntOrder : ORDERED = 2 | struct 3 | type t = int 4 | 5 | val compare : t * t -> order = Int.compare 6 | end 7 | 8 | (* some synonyms *) 9 | structure IntLt : ORDERED = IntOrder 10 | 11 | structure IntInfLt : ORDERED = 12 | struct 13 | type t = IntInf.int 14 | open IntInf 15 | end 16 | -------------------------------------------------------------------------------- /hw/10/code/real.twobody.5day.auto.txt: -------------------------------------------------------------------------------- 1 | 2 | (0.0000E0, 0.0000E0),(0.0000E0, ~1.4960E11) 3 | (0.0000E0, ~1.3299E4),(~2.5730E10, ~1.4517E11) 4 | (~2.3895E3, ~4.0079E4),(~5.0664E10, ~1.3626E11) 5 | (~9.6875E3, ~8.0060E4),(~7.3964E10, ~1.2294E11) 6 | (~2.4439E4, ~1.3243E5),(~9.4783E10, ~1.0551E11) 7 | (~4.9077E4, ~1.9581E5),(~1.1231E11, ~8.4406E10) 8 | -------------------------------------------------------------------------------- /hw/10/Makefile: -------------------------------------------------------------------------------- 1 | all: submit 2 | @: 3 | 4 | package: 5 | PYTHONPATH=/afs/cs.cmu.edu/academic/class/15210-f13/lib/python2.6/site-packages:. /afs/cs.cmu.edu/academic/class/15210-f13/bin/bobb :package 6 | submit: 7 | PYTHONPATH=/afs/cs.cmu.edu/academic/class/15210-f13/lib/python2.6/site-packages:. /afs/cs.cmu.edu/academic/class/15210-f13/bin/bobb :submit 8 | -------------------------------------------------------------------------------- /hw/11/Makefile: -------------------------------------------------------------------------------- 1 | all: submit 2 | @: 3 | 4 | package: 5 | PYTHONPATH=/afs/cs.cmu.edu/academic/class/15210-f13/lib/python2.6/site-packages:. /afs/cs.cmu.edu/academic/class/15210-f13/bin/bobb :package 6 | submit: 7 | PYTHONPATH=/afs/cs.cmu.edu/academic/class/15210-f13/lib/python2.6/site-packages:. /afs/cs.cmu.edu/academic/class/15210-f13/bin/bobb :submit 8 | -------------------------------------------------------------------------------- /hw/12/Makefile: -------------------------------------------------------------------------------- 1 | all: submit 2 | @: 3 | 4 | package: 5 | PYTHONPATH=/afs/cs.cmu.edu/academic/class/15210-f13/lib/python2.6/site-packages:. /afs/cs.cmu.edu/academic/class/15210-f13/bin/bobb :package 6 | submit: 7 | PYTHONPATH=/afs/cs.cmu.edu/academic/class/15210-f13/lib/python2.6/site-packages:. /afs/cs.cmu.edu/academic/class/15210-f13/bin/bobb :submit 8 | -------------------------------------------------------------------------------- /hw/12/code/fib.sml: -------------------------------------------------------------------------------- 1 | signature FIBO = 2 | sig 3 | (* on input n, computes the nth Fibonacci number *) 4 | val fib : IntInf.int -> IntInf.int 5 | end 6 | 7 | structure Fibo : FIBO = 8 | struct 9 | fun fib (n : IntInf.int) : IntInf.int = 10 | case n 11 | of 0 => 0 12 | | 1 => 1 13 | | _ => fib(n-2) + fib(n-1) 14 | end 15 | -------------------------------------------------------------------------------- /hw/12/IN_CASE_OF_EMERGENCY: -------------------------------------------------------------------------------- 1 | # Makefile for 15-150 f13 hw12 2 | # NOTE: if emergency arises and the current Makefile fails, then enter in your command line 3 | # mv IN_CASE_OF_EMERGENCY Makefile 4 | # and type "make" and submit as you've done in the past 5 | 6 | all: 7 | tar -cf hw12.tar code/countingdict.sml code/lazy.sml code/memo.sml 8 | 9 | clean: 10 | rm -rf hw12.tar 11 | -------------------------------------------------------------------------------- /hw/08/code/sources.cm: -------------------------------------------------------------------------------- 1 | group is 2 | $/basis.cm 3 | 4 | (* Question 2 *) 5 | exceptions.sml 6 | exceptions.sig 7 | 8 | (* Question 3 *) 9 | treefind.sml 10 | treefind.sig 11 | 12 | (* Question 4 *) 13 | typedef.sig 14 | stack.sig 15 | stack.sml 16 | 17 | (* Question 6 *) 18 | order.sml 19 | dict.sig 20 | fundict.sml 21 | (*treedict.sml 22 | dictclient.sml *) 23 | -------------------------------------------------------------------------------- /hw/10/code/real.twobody.6day.auto.txt: -------------------------------------------------------------------------------- 1 | 2 | (0.0000E0, 0.0000E0),(0.0000E0, ~1.4960E11) 3 | (0.0000E0, ~1.3299E4),(~2.5730E10, ~1.4517E11) 4 | (~2.3895E3, ~4.0079E4),(~5.0664E10, ~1.3626E11) 5 | (~9.6875E3, ~8.0060E4),(~7.3964E10, ~1.2294E11) 6 | (~2.4439E4, ~1.3243E5),(~9.4783E10, ~1.0551E11) 7 | (~4.9077E4, ~1.9581E5),(~1.1231E11, ~8.4406E10) 8 | (~8.5770E4, ~2.6824E5),(~1.2582E11, ~6.0288E10) 9 | -------------------------------------------------------------------------------- /hw/10/code/comparetranscripts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ## almost all systems will have diff here, but you may need to change this 4 | DIFF=/usr/bin/diff 5 | 6 | for file in *.auto.txt 7 | do 8 | if [[ -e $file ]] 9 | then 10 | echo "checking $file against tests/$file" 11 | diff $file tests/$file 12 | else 13 | echo "tests/$file doesn't exist! this is bad" 14 | fi 15 | done 16 | -------------------------------------------------------------------------------- /hw/08/solutions/code/sources.cm: -------------------------------------------------------------------------------- 1 | group is 2 | $/basis.cm 3 | 4 | (* Question 2 *) 5 | exceptions.sml 6 | 7 | (* Question 3 *) 8 | treefind.sml 9 | 10 | (* Question 4 *) 11 | ../../code/typedef.sig 12 | ../../code/stack.sig 13 | stack.sml 14 | 15 | (* Question 6 *) 16 | ../../code/order.sml 17 | ../../code/dict.sig 18 | fundict.sml 19 | treedict.sml 20 | ../../code/dictclient.sml 21 | -------------------------------------------------------------------------------- /hw/11/IN_CASE_OF_EMERGENCY: -------------------------------------------------------------------------------- 1 | # Makefile for 15-150 f13 hw10 2 | # NOTE: if emergency arises and the current Makefile fails, then enter in your command line 3 | # mv IN_CASE_OF_EMERGENCY Makefile 4 | # and type "make" and submit as you've done in the past 5 | 6 | all: 7 | tar -cf hw11.tar code/graphseq.sml code/alphabeta.sml code/riskless.sml code/jamboree.sml 8 | 9 | clean: 10 | rm -rf hw09.tar 11 | -------------------------------------------------------------------------------- /hw/11/code/graphseq.sig: -------------------------------------------------------------------------------- 1 | signature GRAPHPROBLEMS = 2 | sig 3 | type vertex = int 4 | type edge = vertex * vertex 5 | type graph = vertex Seq.seq Seq.seq 6 | 7 | val to_list : 'a Seq.seq -> 'a list 8 | 9 | val get_neighbors : graph -> vertex -> vertex Seq.seq 10 | val from_edge_seq : edge Seq.seq -> int -> vertex Seq.seq Seq.seq 11 | val is_undirected : graph -> bool 12 | end 13 | 14 | -------------------------------------------------------------------------------- /hw/08/code/stack.sig: -------------------------------------------------------------------------------- 1 | signature STACK = 2 | sig 3 | type stacktype 4 | type stack 5 | 6 | exception StackUnderflow 7 | val empty : unit -> stack 8 | val push : (stack * stacktype) -> stack 9 | val pop : stack -> (stacktype * stack) 10 | val append : (stack * stack) -> stack 11 | val find : (stack * (stacktype -> bool)) -> stack option 12 | val flip : stack -> stack 13 | 14 | end -------------------------------------------------------------------------------- /hw/10/IN_CASE_OF_EMERGENCY: -------------------------------------------------------------------------------- 1 | # Makefile for 15-150 f13 hw10 2 | # NOTE: if emergency arises and the current Makefile fails, then enter in your command line 3 | # mv IN_CASE_OF_EMERGENCY Makefile 4 | # and type "make" and submit as you've done in the past 5 | 6 | all: 7 | tar -cf hw10.tar hw10.pdf code/barnes-hut.sml code/tester.sml code/shrubseq.sml code/sizeseq.sml 8 | 9 | clean: 10 | rm -rf hw09.tar 11 | -------------------------------------------------------------------------------- /hw/08/code/dict.sig: -------------------------------------------------------------------------------- 1 | signature DICT = 2 | sig 3 | 4 | structure Key : ORDERED 5 | 6 | type 'v dict 7 | 8 | val empty : 'v dict 9 | 10 | val insert : 'v dict -> (Key.t * 'v) -> 'v dict 11 | val lookup : 'v dict -> Key.t -> 'v option 12 | val remove : 'v dict -> Key.t -> 'v dict 13 | val map : ('u -> 'v) -> 'u dict -> 'v dict 14 | val filter : ('v -> bool) -> 'v dict -> 'v dict 15 | 16 | end 17 | -------------------------------------------------------------------------------- /lab/10/code/setofsets.sml: -------------------------------------------------------------------------------- 1 | functor SetOfSets (S : SET) : SET = 2 | struct 3 | 4 | (* Impelement PowerSet here *) 5 | exception Unimplemented 6 | 7 | structure DictEqual : EQUAL = 8 | struct 9 | (* write DictEqual here *) 10 | 11 | (* replace unit with the correct type *) 12 | type t = unit 13 | 14 | fun equal (A : t, B : t) : bool = raise Unimplemented 15 | 16 | end 17 | 18 | 19 | end 20 | -------------------------------------------------------------------------------- /lab/10/solutions/setofsets.sml: -------------------------------------------------------------------------------- 1 | functor SetOfSets (S : SET) : SET = 2 | struct 3 | structure SetEqual : EQUAL = 4 | struct 5 | type t = S.set 6 | 7 | fun equal (A : t,B : t) = 8 | S.void (S.union (S.difference A B) (S.difference B A)) 9 | end 10 | 11 | structure SetDict = Dict(SetEqual) 12 | 13 | structure Power = DictSet(SetDict) 14 | 15 | open Power 16 | end 17 | -------------------------------------------------------------------------------- /hw/10/code/real.onebody.2weeks.auto.txt: -------------------------------------------------------------------------------- 1 | 2 | (0.0000E0, 0.0000E0) 3 | (0.0000E0, 0.0000E0) 4 | (0.0000E0, 0.0000E0) 5 | (0.0000E0, 0.0000E0) 6 | (0.0000E0, 0.0000E0) 7 | (0.0000E0, 0.0000E0) 8 | (0.0000E0, 0.0000E0) 9 | (0.0000E0, 0.0000E0) 10 | (0.0000E0, 0.0000E0) 11 | (0.0000E0, 0.0000E0) 12 | (0.0000E0, 0.0000E0) 13 | (0.0000E0, 0.0000E0) 14 | (0.0000E0, 0.0000E0) 15 | (0.0000E0, 0.0000E0) 16 | (0.0000E0, 0.0000E0) 17 | -------------------------------------------------------------------------------- /lab/10/solutions/pairset.sml: -------------------------------------------------------------------------------- 1 | functor PairSet (PE: PAIR_OF_EQUAL) : SET = 2 | struct 3 | 4 | structure CartEqual : EQUAL = 5 | struct 6 | type t = PE.E1.t*PE.E2.t 7 | 8 | fun equal ((a1,b1) : t, (a2,b2) : t) = 9 | PE.E1.equal(a1,a2) andalso PE.E2.equal(b1,b2) 10 | end 11 | 12 | structure CartDict = Dict(CartEqual) 13 | structure CartSet = DictSet(CartDict) 14 | 15 | open CartSet 16 | 17 | end 18 | -------------------------------------------------------------------------------- /hw/08/code/order.sml: -------------------------------------------------------------------------------- 1 | (* some instances of ORDERED for dictionaries *) 2 | signature ORDERED = 3 | sig 4 | type t 5 | val compare : t * t -> order 6 | end 7 | 8 | structure IntOrder : ORDERED = 9 | struct 10 | type t = int 11 | 12 | val compare : t * t -> order = Int.compare 13 | end 14 | 15 | structure StringOrder : ORDERED = 16 | struct 17 | type t = string 18 | 19 | val compare : t * t -> order = String.compare 20 | end 21 | -------------------------------------------------------------------------------- /hw/10/code/real.system.1day.auto.txt: -------------------------------------------------------------------------------- 1 | 2 | (0.0000E0, 0.0000E0),(0.0000E0, 5.7909E10),(0.0000E0, ~1.0821E11),(0.0000E0, ~1.4960E11),(0.0000E0, 2.2794E11),(0.0000E0, 7.7855E11),(0.0000E0, ~1.4334E12),(0.0000E0, 2.8767E12),(0.0000E0, ~4.5034E12) 3 | (0.0000E0, 1.1660E5),(4.1360E10, 2.8359E10),(~3.0257E10, ~9.9746E10),(~2.5730E10, ~1.4517E11),(2.0803E10, 2.2603E11),(1.1292E10, 7.7838E11),(~8.3722E9, ~1.4334E12),(5.8838E9, 2.8767E12),(~4.6915E9, ~4.5034E12) 4 | -------------------------------------------------------------------------------- /lab/09/code/sources.cm: -------------------------------------------------------------------------------- 1 | Group is 2 | $/basis.cm 3 | 4 | intset.sig 5 | ListSets.sml 6 | TreeSets.sml 7 | 8 | (* We could get away with this not being a module, 9 | * but we're putting it here so all you have to 10 | * type is `CM.make "sources.cm"`, rather than 11 | * having to type `CM.make ...` for the modules and 12 | * `use FindException.sml` for the other activity. 13 | *) 14 | FindException.sml 15 | 16 | -------------------------------------------------------------------------------- /hw/10/code/lib/bhargs.sig: -------------------------------------------------------------------------------- 1 | signature BHArgs = 2 | sig 3 | (* what the first bit of the file names should be *) 4 | val prefix : string 5 | 6 | (* threshold value for BH algorithm *) 7 | val thresh : IntInf.int * IntInf.int 8 | 9 | (* the model of the universe *) 10 | structure BB : BOX 11 | structure Mech : MECHANICS 12 | 13 | sharing BB.Plane = Mech.Plane 14 | sharing BB.Plane.Scalar = Mech.Plane.Scalar 15 | sharing BB.Plane.Seq = BB.Seq 16 | end 17 | -------------------------------------------------------------------------------- /lab/09/solutions/code/sources.cm: -------------------------------------------------------------------------------- 1 | Group is 2 | $/basis.cm 3 | 4 | ../../code/intset.sig 5 | ListSets.sml 6 | TreeSets.sml 7 | 8 | (* We could get away with this not being a module, 9 | * but we're putting it here so all you have to 10 | * type is `CM.make "sources.cm"`, rather than 11 | * having to type `CM.make ...` for the modules and 12 | * `use FindException.sml` for the other activity. 13 | *) 14 | FindException.sml 15 | 16 | -------------------------------------------------------------------------------- /hw/01/code/hw01.sml: -------------------------------------------------------------------------------- 1 | (* pi: real *) 2 | val pi : real = 3.14159; 3 | 4 | (* fact: int -> int *) 5 | fun fact (0 : int) : int = 1 6 | | fact n = n * (fact (n - 1)) 7 | 8 | (* f : int -> int *) 9 | fun f (3 : int) : int = 9 10 | | f _ = 4 11 | 12 | (* circ : real -> real *) 13 | fun circ (r : real) : real = 2.0 * pi * r 14 | 15 | (* semicirc : real -> real *) 16 | fun semicirc (r : real) : real = pi * r 17 | 18 | (* area : real -> real *) 19 | fun area (r : real) : real = pi * r * r 20 | -------------------------------------------------------------------------------- /lab/10/code/rbtree.sml: -------------------------------------------------------------------------------- 1 | structure RbTree = 2 | struct 3 | 4 | exception Unimplemented 5 | 6 | (* A possible implementation of RBTs for keys as integers *) 7 | type key = int 8 | val compare : key * key -> order = Int.compare 9 | datatype color = Red | Black 10 | datatype 'v rbtree = Empty 11 | | Node of 'v rbtree * (color * (key * 'v)) * 'v rbtree 12 | 13 | (* Task 3.1 *) 14 | fun isRBT (Empty : 'v rbtree) : bool = true 15 | | isRBT (Node(l,(c,(k,v)),r) : 'v rbtree) : bool = true 16 | 17 | end 18 | -------------------------------------------------------------------------------- /hw/01/solutions/code/hw01-sol.sml: -------------------------------------------------------------------------------- 1 | (* pi: real *) 2 | val pi : real = 3.14159; 3 | 4 | (* fact: int -> int *) 5 | fun fact (0 : int) : int = 1 6 | | fact n = n * (fact (n - 1)) 7 | 8 | (* f : int -> int *) 9 | fun f (9 : int) = 4 10 | | f _ = 5 11 | 12 | (* circ : real -> real *) 13 | fun circ (r : real) : real = 2.0 * pi * r; 14 | 15 | (* semicirc : real -> real *) 16 | fun semicirc (r : real) : real = pi * r; 17 | 18 | (* area : real -> real *) 19 | fun area (d : real) : real = pi * d * d; 20 | 21 | -------------------------------------------------------------------------------- /hw/11/code/sources.cm: -------------------------------------------------------------------------------- 1 | group is 2 | $/basis.cm 3 | ../../../src/sequence/sources.cm 4 | explicit.sml 5 | ../../../src/ordered/sources.cm 6 | minimax.sml 7 | sequtils.sml 8 | 9 | game.sig 10 | map.sig 11 | estimate.sig 12 | player.sig 13 | printer.sig 14 | printer.sml 15 | estimate.sml 16 | humanplayer.sml 17 | alphabeta.sml 18 | jamboree.sml 19 | referee.sml 20 | 21 | riskless.sml 22 | runriskless.sml 23 | 24 | (* Include graphs *) 25 | graphseq.sig 26 | graphseq.sml 27 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This is the git repository for 15-150 Principles of Functional Programming 2 | it is used to handout labs, homework, solutions, and other important 3 | documents. 4 | 5 | For more information about the course, visit the course webpage at 6 | http://www.cs.cmu.edu/~15150/ 7 | 8 | 9 | For more information about git, read the documentation at 10 | http://www.cs.cmu.edu/~15150/resources/git.pdf 11 | 12 | If you have problems or questions, do not hesitate to message the course 13 | staff on Piazza. 14 | 15 | 16 | -------------------------------------------------------------------------------- /hw/12/code/memo.sig: -------------------------------------------------------------------------------- 1 | signature POORMEMOIZER = 2 | sig 3 | (* used to store the mapping *) 4 | structure D : DICT 5 | 6 | (* given a function, returns a poorly memoized version of that function *) 7 | val memo : (D.Key.t -> 'a) -> (D.Key.t -> 'a) 8 | end 9 | 10 | signature MEMOIZER = 11 | sig 12 | (* used to store the mapping *) 13 | structure D : DICT 14 | 15 | (* given a function, returns a memoized version of that function. *) 16 | val memo : ((D.Key.t -> 'a) -> (D.Key.t -> 'a)) -> (D.Key.t -> 'a) 17 | end 18 | -------------------------------------------------------------------------------- /hw/11/code/estimate.sml: -------------------------------------------------------------------------------- 1 | structure Estimate : EST = 2 | struct 3 | type est = int 4 | val minnie_wins = valOf (Int.minInt) 5 | val maxie_wins = valOf (Int.maxInt) 6 | val draw = 0 7 | fun guess x = x 8 | 9 | val compare = Int.compare 10 | 11 | fun toString n = 12 | case (n = minnie_wins , n = maxie_wins , n = draw) of 13 | (true, _, _) => "Minnie wins!" 14 | | (_, true, _) => "Maxie wins!" 15 | | (_, _, true) => "It's a draw!" 16 | | _ => "Guess: " ^ Int.toString n 17 | end 18 | -------------------------------------------------------------------------------- /hw/10/code/support.cm: -------------------------------------------------------------------------------- 1 | group is 2 | $/basis.cm 3 | ../../../src/sequence/sources.cm 4 | lib/bbox.sig 5 | lib/bbox.sml 6 | lib/bhargs.sig 7 | lib/bh.sig 8 | lib/makeplane.sml 9 | lib/mechanics.sig 10 | lib/mechanics.sml 11 | lib/planeargs.sig 12 | lib/ratplaneargs.sml 13 | lib/realplaneargs.sml 14 | lib/scalar.sig 15 | lib/solars.sml 16 | lib/space.sig 17 | lib/makescalar.sml 18 | naiveNBody.sml 19 | lib/simulation.sml 20 | lib/transcripts.sml 21 | 22 | -------------------------------------------------------------------------------- /hw/12/code/lazylist.sig: -------------------------------------------------------------------------------- 1 | signature LAZY_LIST = 2 | sig 3 | 4 | datatype 'a lazylist = Cons of 'a * (unit -> 'a lazylist) 5 | 6 | val show : int -> 'a lazylist -> 'a list 7 | val append : 'a list -> (unit -> 'a lazylist) -> 'a lazylist 8 | val repeat : 'a list -> 'a lazylist 9 | val zip : 'a lazylist -> 'b lazylist -> ('a * 'b) lazylist 10 | val iterate : ('a -> 'a) -> 'a -> 'a lazylist 11 | val compare : ('a * 'a -> bool) -> int -> 'a lazylist -> 'a lazylist -> bool 12 | val match : ('a * 'a -> bool) -> 'a list -> 'a lazylist -> bool 13 | 14 | end 15 | -------------------------------------------------------------------------------- /hw/11/code/map.sig: -------------------------------------------------------------------------------- 1 | signature MAP = 2 | sig 3 | (* Adjacency sequence representation of the game board *) 4 | val board : (string * int Seq.seq) Seq.seq 5 | (* Converts a sequence of node labels to string *) 6 | val board_to_string : string Seq.seq -> string 7 | 8 | (* Number of units that Minnie and Maxie start with *) 9 | val min_start : int 10 | val max_start : int 11 | 12 | (* Win condition: number of units to reach *) 13 | val max_units : int 14 | (* Constraint: maximum units on one territory *) 15 | val max_terri : int 16 | end 17 | -------------------------------------------------------------------------------- /hw/11/code/estimate.sig: -------------------------------------------------------------------------------- 1 | signature EST = 2 | sig 3 | type est 4 | 5 | (* Values that represent the best possible scores, 6 | for Minnie and Maxie as well as the draw score *) 7 | val minnie_wins : est 8 | val maxie_wins : est 9 | val draw : est 10 | 11 | (* Given a value, guesses the score *) 12 | val guess : est -> est 13 | 14 | (* Compares two estimated values and returns an order *) 15 | val compare : (est * est) -> order 16 | 17 | (* Utility function for printing estimated values *) 18 | val toString : est -> string 19 | end 20 | 21 | -------------------------------------------------------------------------------- /hw/12/code/poormemoizer.sml: -------------------------------------------------------------------------------- 1 | functor PoorMemoizer (D : DICT) : POORMEMOIZER = 2 | struct 3 | structure D = D 4 | 5 | fun memo (f : D.Key.t -> 'a) : D.Key.t -> 'a = 6 | let 7 | val hist : 'a D.dict ref = ref D.empty 8 | 9 | fun f_memoed x = 10 | case D.lookup (!hist) x 11 | of SOME(b) => b 12 | | NONE => 13 | let 14 | val res = f x 15 | val _ = (hist := D.insert (!hist) (x,res)) 16 | in 17 | res 18 | end 19 | in 20 | f_memoed 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /hw/11/code/printer.sml: -------------------------------------------------------------------------------- 1 | structure P : Printer = 2 | struct 3 | fun nDups c n = 4 | String.implode (List.tabulate (n, fn i => c)) 5 | 6 | fun pad l s = 7 | let val sl = String.size s 8 | val padding = l - sl 9 | in if padding < 0 then s 10 | else s ^ (nDups #" " padding) 11 | end 12 | 13 | fun padAll ss = 14 | let val ml = Seq.mapreduce String.size 0 Int.max ss 15 | in Seq.map (pad ml) ss 16 | end 17 | 18 | fun labelAll ss = 19 | Seq.tabulate (fn i => "(" ^ (Int.toString i) ^ ") " ^ (Seq.nth i ss)) 20 | (Seq.length ss) 21 | end 22 | -------------------------------------------------------------------------------- /hw/10/code/real.system.2day.auto.txt: -------------------------------------------------------------------------------- 1 | 2 | (0.0000E0, 0.0000E0),(0.0000E0, 5.7909E10),(0.0000E0, ~1.0821E11),(0.0000E0, ~1.4960E11),(0.0000E0, 2.2794E11),(0.0000E0, 7.7855E11),(0.0000E0, ~1.4334E12),(0.0000E0, 2.8767E12),(0.0000E0, ~4.5034E12) 3 | (0.0000E0, 1.1660E5),(4.1360E10, 2.8359E10),(~3.0257E10, ~9.9746E10),(~2.5730E10, ~1.4517E11),(2.0803E10, 2.2603E11),(1.1292E10, 7.7838E11),(~8.3722E9, ~1.4334E12),(5.8838E9, 2.8767E12),(~4.6915E9, ~4.5034E12) 4 | (4.5655E2, 3.4781E5),(5.0222E10, ~2.3473E10),(~5.7867E10, ~8.2555E10),(~5.0664E10, ~1.3625E11),(4.1429E10, 2.2221E11),(2.2583E10, 7.7806E11),(~1.6744E10, ~1.4333E12),(1.1768E10, 2.8766E12),(~9.3830E9, ~4.5034E12) 5 | -------------------------------------------------------------------------------- /hw/10/code/rat.twobody.2day.auto.txt: -------------------------------------------------------------------------------- 1 | 2 | (0, 0),(0, ~149600000000) 3 | (0, ~7266212549208/546390625),(~25729920000, ~25382636804426368/174845) 4 | (~2439755118059437019711420923401562500000000000000000000000000/1590311346462619707618003924003145623664874530822174351549, ~30632408368437424942174439109895599561155746120154478926204587307046384/868931210538302321182718425288531239280265585442509607801827828125),(~81024846937374697931232521501940205165494656976184160582815292160000/1590311346462619707618003924003145623664874530822174351549, ~38333759381110443688669966393301756940197104636728480653091039498634488064/278057987372256742778469896092329996569684987341603074496584905) 5 | -------------------------------------------------------------------------------- /hw/10/code/tests/rat.twobody.2day.auto.txt: -------------------------------------------------------------------------------- 1 | 2 | (0, 0),(0, ~149600000000) 3 | (0, ~7266212549208/546390625),(~25729920000, ~25382636804426368/174845) 4 | (~2439755118059437019711420923401562500000000000000000000000000/1590311346462619707618003924003145623664874530822174351549, ~30632408368437424942174439109895599561155746120154478926204587307046384/868931210538302321182718425288531239280265585442509607801827828125),(~81024846937374697931232521501940205165494656976184160582815292160000/1590311346462619707618003924003145623664874530822174351549, ~38333759381110443688669966393301756940197104636728480653091039498634488064/278057987372256742778469896092329996569684987341603074496584905) 5 | -------------------------------------------------------------------------------- /lab/09/code/FindException.sml: -------------------------------------------------------------------------------- 1 | structure FindExceptions = 2 | struct 3 | 4 | exception NotYetImplemented 5 | exception NotFound 6 | 7 | datatype 'a tree = Empty | Node of 'a tree * 'a * 'a tree 8 | 9 | (* find : ('a -> bool) -> 'a tree -> 'a 10 | * requires: true 11 | * ensures: find p t returns the first value satisfying the predicate 12 | * found during an in-order traversal of the tree. 13 | *) 14 | fun find (p : 'a -> bool) (t : 'a tree) = raise NotYetImplemented 15 | 16 | end 17 | 18 | structure TestFindExceptions = 19 | struct 20 | open FindExceptions 21 | 22 | val emp : int tree = Empty 23 | 24 | (* Your test cases go here! *) 25 | 26 | end 27 | 28 | -------------------------------------------------------------------------------- /hw/10/code/lib/mechanics.sig: -------------------------------------------------------------------------------- 1 | signature MECHANICS = 2 | sig 3 | structure Plane : SPACE 4 | 5 | (* we represent bodies as (mass, location, velocity) *) 6 | type body = Plane.scalar * Plane.point * Plane.vec 7 | 8 | val position : body -> Plane.point 9 | val bodyToString : body -> string 10 | 11 | (* universal gravitational constant for this universe *) 12 | val G : Plane.scalar 13 | 14 | (* acceleration on a point due to a mass and a location *) 15 | val accOnPoint : Plane.point * (Plane.scalar * Plane.point) -> Plane.vec 16 | 17 | (* You shouldn't need these*) 18 | val accOn : body * body -> Plane.vec 19 | val stepBody : body * Plane.vec * Plane.scalar -> body 20 | end 21 | -------------------------------------------------------------------------------- /hw/03/code/lib.sml: -------------------------------------------------------------------------------- 1 | (* inteq : int * int -> bool 2 | * REQUIRES: true 3 | * ENSURES: inteq(x,y) is true iff x = y 4 | *) 5 | fun inteq (l1 : int , l2 : int) : bool = 6 | case Int.compare (l1,l2) 7 | of EQUAL => true 8 | | _ => false 9 | 10 | val false = inteq(~7, 7) 11 | val false =inteq(~7, 0) 12 | val true = inteq(~7, ~7) 13 | 14 | 15 | (* addToEach : int list * int -> int list 16 | * REQUiRES: true 17 | * ENSURES: adds n to each element of the list l 18 | *) 19 | fun addToEach (l : int list, n : int) : int list = 20 | case l of 21 | nil => nil 22 | | x::xs => x + n :: addToEach (xs, n) 23 | 24 | val nil = addToEach (nil, 7) 25 | val 4::5::6::nil = addToEach (1::2::3::nil, 3) 26 | val 3::2::1::nil = addToEach (6::5::4::nil, ~3) 27 | 28 | -------------------------------------------------------------------------------- /lab/10/code/dictset.sml: -------------------------------------------------------------------------------- 1 | functor DictSet (Dict : DICT) : SET = 2 | struct 3 | exception NotInSet 4 | exception Unimplemented 5 | 6 | (* replace unit with the correct types here *) 7 | type elem = Dict.key 8 | type set = unit Dict.dict 9 | 10 | fun empty() = Dict.empty() 11 | 12 | fun void S = Dict.size(S) = 0 13 | 14 | fun find e S = (Dict.find S e) <> NONE 15 | fun insert e S = Dict.insert (fn (x,y) => ()) (e, ()) S 16 | fun delete e S = Dict.delete e S 17 | 18 | fun union s1 s2 = Dict.merge (fn (x,y) => ()) (s1, s2) 19 | fun intersection s1 s2 = Dict.filterk (fn e => find e s1) s2 20 | fun difference s1 s2 = Dict.filterk (fn e => not(find e s1)) s2 21 | 22 | fun toList s = map (fn (k,v) => k) (Dict.toList s) 23 | fun fromList L = Dict.fromList(map (fn k => (k,())) L) 24 | 25 | end 26 | -------------------------------------------------------------------------------- /lab/09/code/intset.sig: -------------------------------------------------------------------------------- 1 | signature INTSET = 2 | sig 3 | type set 4 | 5 | (* raised when 'delete' is called with an element that is not in the set. *) 6 | exception NotInSet 7 | 8 | val empty : unit -> set 9 | 10 | (* return whether an element is in the set or not *) 11 | val find : int -> set -> bool 12 | 13 | (* insert an element into the set *) 14 | val insert : int -> set -> set 15 | 16 | (* delete an element from the set *) 17 | val delete : int -> set -> set 18 | 19 | (* set union - return a set containing all elements in s1 and s2*) 20 | val union : set -> set -> set 21 | 22 | (* set intersection - return a set containing elements in both s1 and s2*) 23 | val intersection : set -> set -> set 24 | 25 | (* set difference - return elements in s1 and not in s2 *) 26 | val difference : set -> set -> set 27 | 28 | end 29 | -------------------------------------------------------------------------------- /lab/09/solutions/code/intset.sig: -------------------------------------------------------------------------------- 1 | signature INTSET = 2 | sig 3 | type set 4 | 5 | (* raised when 'delete' is called with an element that is not in the set. *) 6 | exception NotInSet 7 | 8 | val empty : unit -> set 9 | 10 | (* return whether an element is in the set or not *) 11 | val find : int -> set -> bool 12 | 13 | (* insert an element into the set *) 14 | val insert : int -> set -> set 15 | 16 | (* delete an element from the set *) 17 | val delete : int -> set -> set 18 | 19 | (* set union - return a set containing all elements in s1 and s2*) 20 | val union : set -> set -> set 21 | 22 | (* set intersection - return a set containing elements in both s1 and s2*) 23 | val intersection : set -> set -> set 24 | 25 | (* set difference - return elements in s1 and not in s2 *) 26 | val difference : set -> set -> set 27 | 28 | end 29 | -------------------------------------------------------------------------------- /hw/10/code/naiveNBody.sml: -------------------------------------------------------------------------------- 1 | functor NaiveNBody (A : BHArgs) = 2 | struct 3 | (* structure A = A *) 4 | structure Plane = A.BB.Plane 5 | structure Mech = A.Mech 6 | structure S = A.BB.Seq 7 | open Mech 8 | 9 | (* This is a quadratic pairwise computation of the acceleration vectors, 10 | * much like presented in lecture *) 11 | fun accelerations (bodies : body S.seq) : Plane.vec S.seq = 12 | S.map (fn b1 => Plane.sum (fn b2 => accOn (b1, b2)) bodies) bodies 13 | end 14 | 15 | (* this functor should produce a result that ascribes to a signature giving 16 | just accelerations, and BarnesHut should do the same. We omit such a 17 | signature so that you can test the components of your BarnesHut 18 | implementation independently; it's very hard to debug code when the only 19 | observable incorrect behaivour is "it produces incorrect transcripts 20 | sometimes" *) 21 | -------------------------------------------------------------------------------- /hw/10/code/lib/realplaneargs.sml: -------------------------------------------------------------------------------- 1 | functor RealPlaneArgs (S : SEQUENCE) :> PLANEARGS where Seq = S = 2 | struct 3 | structure Seq = S 4 | 5 | structure ScalarCore : SCALARCORE = 6 | struct 7 | type scalar = real 8 | 9 | val plus : real * real -> real = op+ 10 | val minus : real * real -> real = op- 11 | val times : real * real -> real = op* 12 | val divide : real * real -> real = op/ 13 | val compare : real * real -> order = Real.compare 14 | fun fromRatio (x : IntInf.int, y : IntInf.int) = 15 | Real.fromLargeInt x / Real.fromLargeInt y 16 | fun toString (x : real) = Real.fmt (StringCvt.SCI (SOME 4)) x 17 | end 18 | 19 | structure Scalar = MakeScalar(ScalarCore) 20 | 21 | fun distance (x1, y1) (x2, y2) = 22 | let 23 | val (dx,dy) = (x2 - x1, y2 - y1) 24 | in 25 | (Math.sqrt (dx * dx + dy * dy)) 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /hw/08/code/queues.sml: -------------------------------------------------------------------------------- 1 | (* code for the proof task; you don't need to modify or submit this file *) 2 | 3 | signature QUEUE= 4 | sig 5 | type queue 6 | val emp : queue 7 | val ins : int * queue -> queue 8 | val rem : queue -> (int * queue) option 9 | end 10 | 11 | structure LQ : QUEUE = 12 | struct 13 | type queue = int list 14 | 15 | val emp = [] 16 | fun ins (n , l) = l @ [n] 17 | fun rem l = 18 | case l 19 | of [] => NONE 20 | | x::xs => SOME (x, xs) 21 | end 22 | 23 | structure LLQ : QUEUE = 24 | struct 25 | type queue = (int list) * (int list) 26 | 27 | val emp = ([],[]) 28 | fun ins (n, (front,back)) = (front,n :: back) 29 | 30 | fun rem (front,back) = 31 | case (front,back) 32 | of ([],[]) => NONE 33 | | (x::xs,_) => SOME (x, (xs,back)) 34 | | ([],_) => rem (rev back,[]) 35 | end 36 | -------------------------------------------------------------------------------- /hw/09/code/util.sig: -------------------------------------------------------------------------------- 1 | signature UTIL = 2 | sig 3 | (* peelOff (s1,s2) = SOME s' if s2 = s1 ^ s' 4 | * = NONE otherwise 5 | * 6 | * Ex: 7 | * peelOff ("a","a") = SOME("") 8 | * peelOff ("a","ab") = SOME("b") 9 | * peelOff ("a","c") = NONE 10 | *) 11 | val peelOff : string * string -> string option 12 | 13 | (* peelInt s = SOME (i,s') if the longest non-empty prefix of s 14 | * comprised only of an optional leading #"~" and following digits 15 | * parses to the integer i, and s = i ^ s' 16 | * = NONE otherwise 17 | * 18 | * Ex: 19 | * peelInt "55hello" = SOME(55,"hello") 20 | * peelInt "~55hello" = SOME(~55,"hello") 21 | * peelInt "-55hello" = NONE 22 | * peelInt "hello55" = NONE 23 | * peelInt "12~100" = SOME(12,"~100") 24 | *) 25 | val peelInt : string -> (int * string) option 26 | end 27 | -------------------------------------------------------------------------------- /hw/10/code/lib/bh.sig: -------------------------------------------------------------------------------- 1 | signature BARNESHUT = sig 2 | structure Args : BHArgs 3 | structure BB : BOX = Args.BB 4 | structure Mech : MECHANICS = Args.Mech 5 | structure Plane : SPACE = BB.Plane 6 | structure Seq : SEQUENCE = BB.Seq 7 | 8 | (* this is the core idea of the barnes-hut algorithm *) 9 | (* a bhtree is a finitely branching tree of bodies that also 10 | * stores the center of mass and bounding box containing it's 11 | * children *) 12 | datatype bhtree = 13 | Empty 14 | | Single of Mech.body 15 | | Cell of (Plane.scalar * Plane.point) * Plane.scalar * (bhtree Seq.seq) 16 | (* ((mass, center), box diameter, quadrants*) 17 | 18 | val barycenter : (Plane.scalar * Plane.point) Seq.seq -> Plane.scalar * Plane.point 19 | val quarters : BB.box -> BB.box Seq.seq 20 | val compute_tree : Mech.body Seq.seq -> bhtree 21 | val too_far : Plane.point -> Plane.point -> Plane.scalar -> Plane.scalar -> bool 22 | 23 | val accelerations : Mech.body Seq.seq -> BB.Plane.vec Seq.seq 24 | end 25 | -------------------------------------------------------------------------------- /lab/10/code/set.sig: -------------------------------------------------------------------------------- 1 | signature SET = 2 | sig 3 | type elem 4 | type set 5 | 6 | (* return an empty set *) 7 | val empty : unit -> set 8 | 9 | (* return whether set is an empty set or not *) 10 | val void : set -> bool 11 | 12 | (* return whether an element is in the set or not *) 13 | val find : elem -> set -> bool 14 | 15 | (* insert an element into the set *) 16 | val insert : elem -> set -> set 17 | 18 | (* delete an element from the set *) 19 | val delete : elem -> set -> set 20 | 21 | (* return a set containing all elements in s1 and s2*) 22 | val union : set -> set -> set 23 | 24 | (* return a set containing elements in both s1 and s2 *) 25 | val intersection : set -> set -> set 26 | 27 | (* return elements in s1 and not in s2 *) 28 | val difference : set -> set -> set 29 | 30 | (* return a list containing all elements in s *) 31 | val toList : set -> elem list 32 | 33 | (* return a set containing all elements in L *) 34 | val fromList : elem list -> set 35 | 36 | end 37 | -------------------------------------------------------------------------------- /lab/10/solutions/dictset.sml: -------------------------------------------------------------------------------- 1 | functor DictSet (Dict : DICT) : SET = 2 | struct 3 | 4 | exception NotInSet 5 | 6 | type elem = Dict.key 7 | 8 | type set = unit Dict.dict 9 | 10 | val empty = Dict.empty 11 | 12 | fun void (S : set) : bool = Dict.size S = 0 13 | 14 | fun find (e : elem) (S : set) : bool = 15 | case Dict.find S e of 16 | NONE => false 17 | | _ => true 18 | 19 | fun insert (e : elem) (S : set) : set = 20 | Dict.insert (fn (x,y) => ()) (e,()) S 21 | 22 | fun delete (e : elem) (S : set) : set = 23 | Dict.delete e S 24 | 25 | fun union (s1 : set) (s2 : set) : set = 26 | Dict.merge (fn (x,y) => ()) (s1, s2) 27 | 28 | fun intersection (s1 : set) (s2 : set) : set = 29 | Dict.filterk (fn x => find x s1) s2 30 | 31 | fun difference (s1 : set) (s2 : set) : set = 32 | Dict.filterk (fn x => not (find x s1)) s2 33 | 34 | fun toList (s : set) : elem list = 35 | List.map (fn(x,y) => x) (Dict.toList s) 36 | 37 | fun fromList (L : elem list) : set = 38 | Dict.fromList (List.map (fn x => (x,())) L) 39 | 40 | end 41 | -------------------------------------------------------------------------------- /hw/08/solutions/code/exceptions.sml: -------------------------------------------------------------------------------- 1 | (* What went wrong? : The last call to factorizer 2 | * did not account for the Prime exception. *) 3 | (* How did you fix it? : We handled the Prime exception in this case. *) 4 | structure Factorize = 5 | struct 6 | exception Prime 7 | 8 | (* next_divisor : int * int -> int *) 9 | (* REQUIRES : n > 1, k <= n, k > 1 *) 10 | (* ENSURES : evaluates to the smallest divisor of n 11 | * which is at least k *) 12 | fun next_divisor (n : int, k : int) : int = 13 | case n mod k of 14 | 0 => k 15 | | _ => next_divisor (n, k + 1) 16 | 17 | (* factorizer : int -> int list *) 18 | (* REQUIRES : n > 1, n is not prime *) 19 | (* ENSURES : evaluates to a list of the prime divisors of n *) 20 | fun factorizer (n : int) : int list = 21 | let 22 | val q = next_divisor (n, 2) 23 | in 24 | if q = n then raise Prime 25 | else 26 | let 27 | val q_divs = factorizer(q) handle Prime => [q] 28 | in 29 | (q_divs @ factorizer(n div q)) 30 | handle Prime => (q_divs @ [n div q]) 31 | end 32 | end 33 | end 34 | 35 | 36 | -------------------------------------------------------------------------------- /hw/12/code/memo_reference.sml: -------------------------------------------------------------------------------- 1 | (* the code in this file is provided for testing and task 4.2 *) 2 | structure Fibo : FIBO = 3 | struct 4 | fun fib (n : IntInf.int) : IntInf.int = 5 | case n 6 | of 0 => 0 7 | | 1 => 1 8 | | _ => fib(n-2) + fib(n-1) 9 | end 10 | 11 | functor PoorMemoizer (D : DICT) : POORMEMOIZER = 12 | struct 13 | structure D = D 14 | 15 | fun memo (f : D.Key.t -> 'a) : D.Key.t -> 'a = 16 | let 17 | val hist : 'a D.dict ref = ref D.empty 18 | 19 | fun f_memoed x = 20 | case D.lookup (!hist) x 21 | of SOME(b) => b 22 | | NONE => 23 | let 24 | val res = f x 25 | val _ = (hist := D.insert (!hist) (x,res)) 26 | in 27 | res 28 | end 29 | in 30 | f_memoed 31 | end 32 | end 33 | 34 | structure TreeMemoFibo = MemoedFibo(TreeDict(IntInfLt)) 35 | 36 | structure PoorAutoMemoFibo : FIBO = 37 | struct 38 | structure TreeIntInfMemoizer = PoorMemoizer(TreeDict(IntInfLt)) 39 | val fib = TreeIntInfMemoizer.memo Fibo.fib 40 | end 41 | -------------------------------------------------------------------------------- /hw/05/code/lib.sml: -------------------------------------------------------------------------------- 1 | datatype 'a shrub = Leaf of 'a 2 | | Branch of 'a shrub * 'a shrub 3 | 4 | (* ---------------------------------------------------------------------- *) 5 | (* Other provided functions *) 6 | 7 | (* Purpose: Returns SOME of the nth (starting from index 0) element of the 8 | * argument list if the list has at least n+1 elements. Otherwise, the result 9 | * is NONE. 10 | *) 11 | fun nth (l : 'a list, n : int) : 'a option = 12 | case l of 13 | nil => NONE 14 | | x::xs => (case n of 15 | 0 => SOME x 16 | | _ => nth (xs, n-1)) 17 | 18 | (* Purpose: Converts an argument list into a function that maps a natural 19 | * number int to the element of the list in that position if there is one. 20 | * Otherwise, the function maps the int to the value x. 21 | *) 22 | fun listToFun (x : 'a, l : 'a list) : int -> 'a = 23 | fn y => case nth (l, y) of NONE => x | SOME x' => x' 24 | 25 | fun width [] = 0 26 | | width (l::_) = length l 27 | 28 | val height = List.length 29 | 30 | (* Purpose : Hiding ListPair library *) 31 | 32 | fun zip (a,b) = ListPair.zip (a,b) 33 | -------------------------------------------------------------------------------- /hw/10/code/lib/makescalar.sml: -------------------------------------------------------------------------------- 1 | functor MakeScalar(SC : SCALARCORE) : SCALAR = 2 | struct 3 | open SC 4 | fun gte (x : scalar, y : scalar) : bool= 5 | case compare(x,y) 6 | of LESS => false 7 | | _ => true 8 | 9 | fun lte (x : scalar, y : scalar) : bool = 10 | case compare(x,y) 11 | of GREATER => false 12 | | _ => true 13 | 14 | fun min (x : scalar, y : scalar) : scalar = 15 | case compare(x,y) 16 | of LESS => x 17 | | _ => y 18 | 19 | fun max (x : scalar, y : scalar) : scalar= 20 | case compare(x,y) 21 | of GREATER => x 22 | | _ => y 23 | 24 | fun eq (x : scalar, y : scalar) : bool = 25 | case compare(x,y) 26 | of EQUAL => true 27 | | _ => false 28 | 29 | fun fromInt x = fromRatio (x,1) 30 | val zero = fromInt 0 31 | val one = fromInt 1 32 | 33 | (* simple and slow pow: assume exp : nat, exp many mults. *) 34 | fun pow (base : scalar, exp : int) : scalar = 35 | case exp 36 | of 0 => one 37 | | _ => times(base, pow(base, exp - 1)) 38 | 39 | fun invert (x : scalar) = divide(one, x) 40 | 41 | fun negate (x : scalar) = times(x, fromInt(~1)) 42 | end 43 | -------------------------------------------------------------------------------- /hw/08/code/dictclient.sml: -------------------------------------------------------------------------------- 1 | structure StrDict = FunDict (StringOrder : ORDERED) 2 | 3 | val sipairs = [("one", 1), ("two", 2), ("three", 3), ("four", 4), ("five", 5)] 4 | val sd5 = List.foldl (fn (p, d) => StrDict.insert d p) StrDict.empty sipairs 5 | 6 | val SOME 3 = StrDict.lookup sd5 "three" 7 | val SOME 5 = StrDict.lookup sd5 "five" 8 | 9 | val sd4 = StrDict.remove sd5 "four" 10 | 11 | val NONE = StrDict.lookup sd4 "four" 12 | val SOME 5 = StrDict.lookup sd4 "five" 13 | 14 | val ssd5 = StrDict.map Int.toString sd5 15 | 16 | val NONE = StrDict.lookup ssd5 "six" 17 | val SOME "5" = StrDict.lookup ssd5 "five" 18 | 19 | val sd3 = StrDict.filter (fn x => x > 2) sd5 20 | 21 | val NONE = StrDict.lookup sd3 "one" 22 | val SOME 3 = StrDict.lookup sd3 "three" 23 | val SOME 5 = StrDict.lookup sd3 "five" 24 | 25 | structure IntDict = FunDict (IntOrder : ORDERED) 26 | 27 | val ispairs = [(1, "one"), (2, "two"), (3, "three"), (4, "four"), (5, "five")] 28 | val id5 = List.foldl (fn (p, d) => IntDict.insert d p) IntDict.empty ispairs 29 | 30 | val SOME "three" = IntDict.lookup id5 3 31 | val SOME "five" = IntDict.lookup id5 5 32 | 33 | val id4 = IntDict.remove id5 4 34 | 35 | val NONE = IntDict.lookup id4 4 36 | val SOME "five" = IntDict.lookup id4 5 37 | 38 | -------------------------------------------------------------------------------- /hw/10/code/lib/scalar.sig: -------------------------------------------------------------------------------- 1 | (* these are actually dependent on the particular implementation of scalars *) 2 | signature SCALARCORE = 3 | sig 4 | type scalar 5 | 6 | val plus : scalar * scalar -> scalar (* plus(s1,s2) means s1 + s2 *) 7 | val minus : scalar * scalar -> scalar (* minus(s1,s2) means s1 - s2 *) 8 | val times : scalar * scalar -> scalar (* times(s1,s2) means s1 * s2 *) 9 | val divide : scalar * scalar -> scalar (* divide(s1,s2) means s1 / s2 *) 10 | 11 | val compare : scalar * scalar -> order (* compare two scalars *) 12 | val fromRatio : IntInf.int * IntInf.int -> scalar 13 | val toString : scalar -> string 14 | end 15 | 16 | (* these guys are all derived forms, so let's save code and derive them *) 17 | signature SCALAR = 18 | sig 19 | include SCALARCORE 20 | 21 | val negate : scalar -> scalar 22 | 23 | val gte : scalar * scalar -> bool 24 | val lte : scalar * scalar -> bool 25 | val eq : scalar * scalar -> bool 26 | val min : scalar * scalar -> scalar 27 | val max : scalar * scalar -> scalar 28 | 29 | val invert : scalar -> scalar 30 | 31 | val zero : scalar 32 | val one : scalar 33 | val fromInt : IntInf.int -> scalar 34 | val pow : scalar * int -> scalar 35 | end 36 | 37 | (* see makescalar.sml for the derivations of the derived forms *) 38 | -------------------------------------------------------------------------------- /lab/09/solutions/code/FindException.sml: -------------------------------------------------------------------------------- 1 | structure FindExceptions = 2 | struct 3 | 4 | exception NotFound 5 | 6 | datatype 'a tree = Empty | Node of 'a tree * 'a * 'a tree 7 | 8 | (* find : ('a -> bool) -> 'a tree -> 'a 9 | * requires: true 10 | * ensures: find p t returns the first value satisfying the predicate 11 | * found during an in-order traversal of the tree. 12 | *) 13 | fun find (p : 'a -> bool) (Empty : 'a tree) = raise NotFound 14 | | find (p) (Node(l, x, r)) = if (p x) 15 | then x 16 | else ((find p l) 17 | handle NotFound => (find p r)) 18 | end 19 | 20 | structure TestFindExceptions = 21 | struct 22 | open FindExceptions 23 | 24 | val emp : int tree = Empty 25 | val oneFive : int tree = Node(Empty, 5, Empty) 26 | val oneSix : int tree = Node(Empty, 6, Empty) 27 | val oneSeven : int tree = Node(Empty, 7, Empty) 28 | 29 | val oneOdd : int tree = Node(Node(Empty, 2, Empty), 30 | 6, 31 | Node(Empty, 8, Node(Empty, 5, Empty))) 32 | 33 | val ~1 = find (fn x => x=6) oneFive handle NotFound => ~1 34 | val 6 = find (fn x => x=6) oneSix handle NotFound => ~1 35 | val 5 = find (fn x => x mod 2 = 1) oneOdd 36 | 37 | end 38 | 39 | -------------------------------------------------------------------------------- /src/sequence/sequencecore-sig.sml: -------------------------------------------------------------------------------- 1 | signature SEQUENCECORE = 2 | sig 3 | type 'a seq 4 | 5 | exception Range of string 6 | 7 | (* length == n *) 8 | val length : 'a seq -> int 9 | (* nth i == x_i if 0 <= i < n, raises Range otherwise *) 10 | val nth : int -> 'a seq -> 'a 11 | 12 | (* tabulate f n == *) 13 | val tabulate : (int -> 'a) -> int -> 'a seq 14 | (* filter p == 15 | * that is, filter p s computes the sequence of all elements si of s such that 16 | * p si == true, in the original order. *) 17 | val filter : ('a -> bool) -> 'a seq -> 'a seq 18 | 19 | (* map f == *) 20 | val map : ('a -> 'b) -> 'a seq -> 'b seq 21 | (* reduce op b == x_0 op x2 ... op x_(n-1), 22 | * that is, reduce applies the given function between all elements of the 23 | * input sequence, using b as the base case. *) 24 | val reduce : (('a * 'a) -> 'a) -> 'a -> 'a seq -> 'a 25 | 26 | datatype 'a lview = Nil | Cons of 'a * 'a seq 27 | datatype 'a tview = Empty | Leaf of 'a | Node of 'a seq * 'a seq 28 | 29 | val showl : 'a seq -> 'a lview 30 | val hidel : 'a lview -> 'a seq 31 | 32 | val showt : 'a seq -> 'a tview 33 | val hidet : 'a tview -> 'a seq 34 | end 35 | -------------------------------------------------------------------------------- /hw/11/code/game.sig: -------------------------------------------------------------------------------- 1 | signature GAME = 2 | sig 3 | datatype player = Minnie | Maxie 4 | 5 | datatype outcome = Winner of player | Draw 6 | datatype status = Over of outcome | In_play 7 | 8 | structure Est : EST 9 | 10 | type state (* state of the game; e.g. board and player *) 11 | type move (* moves *) 12 | 13 | (* views of the state: *) 14 | (* assuming state is not over, generates non-empty seq of valid moves *) 15 | val moves : state -> move Seq.seq 16 | val status : state -> status 17 | val player : state -> player 18 | 19 | (* initial state and transitions: *) 20 | val start : state 21 | (* assumes move is valid in that state *) 22 | val make_move : (state * move) -> state 23 | 24 | (* The sign of a guess is absolute, not relative to whose turn it is: 25 | negative values are better for Minnie 26 | and positive values are better for Maxie. *) 27 | type est = Est.est 28 | (* estimate the value of the state, which is assumed to be In_play *) 29 | val estimate : state -> est 30 | 31 | val move_to_string : move -> string 32 | val state_to_string : state -> string 33 | 34 | (* ensures move is valid in that state; 35 | string is single line, and *not* newline terminated *) 36 | val parse_move : state -> string -> move option 37 | end 38 | 39 | -------------------------------------------------------------------------------- /hw/12/code/lazylist.sml: -------------------------------------------------------------------------------- 1 | structure LazyList : LAZY_LIST = 2 | struct 3 | datatype 'a lazylist = Cons of 'a * (unit -> 'a lazylist) 4 | 5 | (* show : int -> 'a lazylist -> 'a list *) 6 | fun show 0 _ = [ ] 7 | | show n (Cons(x, h)) = x :: show (n-1) (h ()) 8 | 9 | (* append : 'a list -> (unit -> 'a lazylist) -> 'a lazylist *) 10 | fun append [] h = h () 11 | | append (x :: xs) h = Cons(x, fn () => append xs h) 12 | 13 | (* repeat : 'a list -> 'a lazylist *) 14 | (* REQUIRES xs not empty *) 15 | (* ENSURES repeat(xs) terminates *) 16 | fun repeat xs = append xs (fn ( ) => repeat xs) 17 | 18 | (* zip : 'a lazylist -> 'a lazylist -> 'a lazylist *) 19 | fun zip (Cons(x1, f1)) (Cons(x2, f2)) = 20 | Cons((x1, x2), fn () => zip (f1 ()) (f2 ())) 21 | 22 | (* iterate : ('a -> 'a) -> 'a -> 'a lazylist *) 23 | fun iterate next z = Cons(z, fn () => iterate next (next z)) 24 | 25 | (* compare : ('a * 'a -> bool) -> int -> 'a lazylist -> 'a lazylist -> bool *) 26 | fun compare eq 0 _ _ = true 27 | | compare eq n (Cons(x1, f1)) (Cons(x2, f2)) = 28 | eq (x1, x2) andalso compare eq (n - 1) (f1 ()) (f2 ()) 29 | 30 | (* match : ('a * 'a -> bool) -> 'a list -> 'a lazylist -> bool *) 31 | fun match eq [] _ = true 32 | | match eq (x1 :: xs) (Cons(x2, f)) = 33 | eq (x1, x2) andalso match eq xs (f ()) 34 | 35 | end -------------------------------------------------------------------------------- /hw/08/code/treefind.sml: -------------------------------------------------------------------------------- 1 | structure TreeFind : TREEFIND = 2 | struct 3 | datatype 'a ntree = Empty 4 | | Node of 'a * 'a ntree list 5 | type 'a tree = 'a ntree 6 | 7 | exception NoSubtree 8 | 9 | (* fun : ('a -> bool) -> 'a tree -> 'a tree *) 10 | (* REQUIRES: true *) 11 | (* ENSURES: find p T evaluates to a subtree of T whose root satisfies p 12 | * and raises NoSubtree if no such subtree exists *) 13 | fun find (p : 'a -> bool) (Empty : 'a tree) : 'a tree = raise NoSubtree 14 | | find (p : 'a -> bool) (Node(x,[]) : 'a tree) : 'a tree = 15 | if p x 16 | then Node(x,[]) 17 | else raise NoSubtree 18 | | find (p : 'a -> bool) (Node(x,y::L) : 'a tree) : 'a tree = 19 | if p x 20 | then Node(x,y::L) 21 | else find p y handle NoSubtree => find p (Node(x,L)) 22 | 23 | end 24 | 25 | 26 | structure TestTreeFind = 27 | struct 28 | 29 | (* Tests for find *) 30 | val testTree1 = TreeFind.Node(1,[TreeFind.Node(2,[]),TreeFind.Node(3,[])]) 31 | val testTree2 = TreeFind.Node(1,[]) 32 | 33 | val (TreeFind.Node(1,[TreeFind.Node(2,[]),TreeFind.Node(3,[])])) = 34 | TreeFind.find (fn x => x = 1) testTree1 35 | val (TreeFind.Node(2,[])) = TreeFind.find (fn x => x = 2) testTree1 36 | val (TreeFind.Node(3,[])) = TreeFind.find (fn x => x = 3) testTree1 37 | val (TreeFind.Node(1,[])) = TreeFind.find (fn x => x = 1) testTree2 38 | 39 | end 40 | -------------------------------------------------------------------------------- /hw/08/code/exceptions.sml: -------------------------------------------------------------------------------- 1 | (* What went wrong? : The second recursive call to factorizer did not handle the exception Prime. 2 | * How did you fix it? : I added an Prime exxception handler to the second recursive call to 3 | * factorizer to return the correct prime factorization. 4 | *) 5 | structure Factorize : FACTORIZE = 6 | struct 7 | exception Prime 8 | 9 | (* next_divisor : int * int -> int *) 10 | (* REQUIRES : n > 1, k <= n, k > 1 *) 11 | (* ENSURES : evaluates to the smallest divisor of n 12 | * which is at least k *) 13 | fun next_divisor (n : int, k : int) : int = 14 | case n mod k of 15 | 0 => k 16 | | _ => next_divisor (n, k + 1) 17 | 18 | (* factorizer : int -> int list *) 19 | (* REQUIRES : n > 1, n is not prime *) 20 | (* ENSURES : evaluates to a list of the prime divisors of n *) 21 | fun factorizer (n : int) : int list = 22 | let 23 | val q = next_divisor (n, 2) 24 | in 25 | if q = n then raise Prime 26 | else 27 | let 28 | val q_divs = factorizer q handle Prime => [q] 29 | in 30 | q_divs @ factorizer (n div q) handle Prime => [q, n div q] 31 | end 32 | end 33 | 34 | end 35 | 36 | 37 | structure TestFactorize = 38 | struct 39 | 40 | (* Tests for factorizer *) 41 | val [2,3,7] = Factorize.factorizer 42 42 | val [3,3,43] = Factorize.factorizer 387 43 | val [2,7,683] = Factorize.factorizer 9562 44 | 45 | end 46 | -------------------------------------------------------------------------------- /hw/10/code/lib/bbox.sig: -------------------------------------------------------------------------------- 1 | signature BOX = 2 | sig 3 | structure Plane : SPACE 4 | structure Seq : SEQUENCE 5 | 6 | type box 7 | val toString : box -> string 8 | 9 | (* inside bb p evaluates to true if and only if the point p is in bb *) 10 | val inside : box -> Plane.point -> bool 11 | 12 | (* Returns the four corners of the bounding box in top left, top right, 13 | * bottom left, bottom right order *) 14 | val vertices : box -> Plane.point Seq.seq 15 | 16 | (* fromPoint p returns the smallest bounding box containing p 17 | * Namely, it returns the box consisting of the single point p 18 | *) 19 | val fromPoint : Plane.point -> box 20 | 21 | (* union (bb1, bb2) returns the smallest bounding box containing both 22 | * all the points in bb1 and all the points in bb2 23 | *) 24 | val union : box * box -> box 25 | 26 | (* fromPoints (p1, p2) returns the smallest bounding box containing both 27 | * p1 and p2 28 | *) 29 | val fromPoints : Plane.point * Plane.point -> box 30 | 31 | (* Computes the center point of the bounding box *) 32 | val center : box -> Plane.point 33 | 34 | (* Computes the minimum bounding box of a sequence of points, 35 | or returns NONE if the sequence is empty. 36 | *) 37 | val hull : Plane.point Seq.seq -> box option 38 | 39 | (* Finds the diameter of the bounding box (distance from 40 | top left to bottom right *) 41 | val diameter : box -> Plane.scalar 42 | end 43 | -------------------------------------------------------------------------------- /hw/11/code/sequtils.sml: -------------------------------------------------------------------------------- 1 | structure SeqUtils : 2 | sig 3 | (* assume sequence is non-empty *) 4 | val reduce1 : ('a * 'a -> 'a) -> 'a Seq.seq -> 'a 5 | val null : 'a Seq.seq -> bool 6 | 7 | val seqToList : 'a Seq.seq -> 'a list 8 | val seqFromList : 'a list -> 'a Seq.seq 9 | end = 10 | struct 11 | fun reduce1 (c : 'a * 'a -> 'a) (s : 'a Seq.seq) : 'a = 12 | let 13 | fun mergeo (x : 'a option , y : 'a option) : 'a option = 14 | case (x , y) of 15 | (NONE , y) => y 16 | | (x , NONE) => x 17 | | (SOME x, SOME y) => SOME (c (x,y)) 18 | in 19 | case Seq.mapreduce SOME NONE mergeo s of 20 | SOME x => x 21 | | NONE => raise Fail "called reduce1 on an empty sequence" 22 | end 23 | 24 | fun null s = Seq.length s = 0 25 | 26 | fun seqToList s = Seq.mapreduce (fn x => [x]) [] op@ s 27 | fun seqFromList l = List.foldr (fn (x,y) => Seq.cons x y) (Seq.empty()) l 28 | 29 | end 30 | 31 | structure TestUtil = 32 | struct 33 | 34 | val test = Seq.cons (((), 84)) (Seq.cons ((), 32) (Seq.cons ((), ~4) (Seq.cons ((), 0) (Seq.empty())))) 35 | structure O = OrderUtils (PairSecondOrder (struct type left = unit structure Right = IntLt end)) 36 | val test = SeqUtils.reduce1 O.min test 37 | 38 | val true = SeqUtils.null (Seq.empty ()) 39 | val false = SeqUtils.null (Seq.tabulate (fn i => i) 1) 40 | end 41 | -------------------------------------------------------------------------------- /hw/11/code/humanplayer.sml: -------------------------------------------------------------------------------- 1 | (* The HumanPlayer just gets moves from what the user types in. 2 | * It is a functor that takes a game so that it knows how to 3 | * represent moves and the game state and knows how to find out if 4 | * a move is legal and whose turn it is. 5 | * We've written this one for you so you can use it to test your game. 6 | *) 7 | functor HumanPlayer (G : GAME) : PLAYER = 8 | struct 9 | structure Game = G 10 | 11 | fun next_move state = 12 | let val () = 13 | (print ((case (Game.player state) of 14 | Game.Maxie => "Maxie" 15 | | Game.Minnie => "Minnie") 16 | ^ ", please type your move: ")) 17 | in 18 | case TextIO.inputLine TextIO.stdIn of 19 | NONE => raise Fail "Failed to read a line of input from stdin" 20 | | SOME input => 21 | let val input = 22 | (* eat the newline character from the end of input *) 23 | String.substring(input, 0, String.size(input) - 1) 24 | in 25 | case Game.parse_move state input of 26 | SOME m => m 27 | | NONE => 28 | let val () = print ("Bad move for this state: " 29 | ^ input ^ "\n") 30 | in 31 | next_move state 32 | end 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /lab/10/code/dict.sig: -------------------------------------------------------------------------------- 1 | signature DICT = 2 | sig 3 | 4 | type 'a dict 5 | type key 6 | 7 | (* return the number of keys in the dictionary *) 8 | val size : 'a dict -> int 9 | 10 | (* returns SOME v if d contains the mapping (k -> v) and NONE otherwise *) 11 | val find : 'a dict -> key -> 'a option 12 | 13 | (* returns a dict with the key value pair (k -> v) if k is not already in dict 14 | * if k is already in dict, call f to determine the key's value*) 15 | val insert : ('a * 'a -> 'a) -> (key * 'a) -> 'a dict -> 'a dict 16 | 17 | (* returns a dict with k removed *) 18 | val delete : key -> 'a dict -> 'a dict 19 | 20 | (* returns the empty dict *) 21 | val empty : unit -> 'a dict 22 | 23 | (* returns a singleton dict with only (k -> v) *) 24 | val singleton : key * 'a -> 'a dict 25 | 26 | (* returns dict with f mapped to all values *) 27 | val map : ('a -> 'b) -> 'a dict -> 'b dict 28 | 29 | (* returns dict with all values such that f v = true *) 30 | val filter : ('a -> bool) -> 'a dict -> 'a dict 31 | 32 | (* returns dict with all keys such that f k = true *) 33 | val filterk : (key -> bool) -> 'a dict -> 'a dict 34 | 35 | (* returns the dict that contains all keys in both d1 and d2 36 | * if there are duplicate keys, call f to determine the key's value *) 37 | val merge : ('a * 'a -> 'a) -> ('a dict * 'a dict) -> 'a dict 38 | 39 | (* returns the list representation of a dict [(k1,v1), ,(kn,vn)] *) 40 | val toList : 'a dict -> (key * 'a) list 41 | 42 | (* returns the dict given a list representation *) 43 | val fromList : (key * 'a) list -> 'a dict 44 | 45 | end 46 | -------------------------------------------------------------------------------- /lab/01/code/lab01.sml: -------------------------------------------------------------------------------- 1 | (* ---------------------------------------------------------------------- *) 2 | (* For Sec 7.1 *) 3 | fun intToString (x : int) : string = Int.toString x 4 | (* ---------------------------------------------------------------------- *) 5 | 6 | (* ---------------------------------------------------------------------- *) 7 | 8 | (* Code from class *) 9 | 10 | (* sum : int list -> int*) 11 | (* REQUIRES: true*) 12 | (* ENSURES: sum(L) evaluates to the sum of the integers in L.*) 13 | fun sum ([ ] : int list) : int = 0 14 | | sum (x::L) = x + (sum L) 15 | 16 | (* count : int list list -> int*) 17 | (* REQUIRES: true*) 18 | (* ENSURES: count(R) evaluates to the sum of the integers in R.*) 19 | fun count ([ ] : int list list) : int = 0 20 | | count (r::R) = (sum r) + (count R) 21 | 22 | (* mult : int list -> int*) 23 | (* REQUIRES: true*) 24 | (* ENSURES: mult(L) evaluates to the product of the integers in L.*) 25 | fun mult [ ] = 1 26 | | mult (x::L) = x * (mult L); 27 | 28 | (* mult’ : int list * int -> int *) 29 | (* REQUIRES: true*) 30 | (* ENSURES: mult’(L, a) evaluates to the product of a and the integers in L.*) 31 | fun mult’ ([ ], a) = a 32 | | mult’ (x::L, a) = mult’ (L, x*a); 33 | 34 | (* Mult : int list list -> int *) 35 | (* REQUIRES: true*) 36 | (* ENSURES: Mult(R) evaluates to the product of all the integers in the lists of R.*) 37 | fun Mult [ ] = 1 38 | | Mult (r::R) = mult(r) * Mult(R); 39 | 40 | (* Mult’ : int list list * int -> int*) 41 | (* REQUIRES: true*) 42 | (* ENSURES: Mult'(R) evaluates to the product of a and all the integers in the lists of R.*) 43 | fun Mult' [ ] = 1 44 | | Mult' (r::R) = Mult'(R, mult'(r, a)); 45 | 46 | -------------------------------------------------------------------------------- /hw/11/code/runriskless.sml: -------------------------------------------------------------------------------- 1 | functor MMTwo(G : GAME) = MiniMax(struct structure G = G 2 | val search_depth = 2 3 | end) 4 | 5 | functor MMFour(G : GAME) = MiniMax(struct structure G = G 6 | val search_depth = 4 7 | end) 8 | 9 | functor ABFour(G : GAME) = AlphaBeta(struct structure G = G 10 | val search_depth = 4 11 | end) 12 | 13 | functor ABSix(G : GAME) = AlphaBeta(struct structure G = G 14 | val search_depth = 6 15 | end) 16 | 17 | functor Jam(G : GAME) = Jamboree(struct structure G = G 18 | val search_depth = 6 19 | val prune_percentage = 0.5 20 | end) 21 | 22 | 23 | structure Risk_HvMM = Referee(struct 24 | structure Maxie = HumanPlayer(RL2) 25 | structure Minnie = MMTwo(RL2) 26 | end) 27 | 28 | 29 | (* Task 5.4 *) 30 | structure Risk_HvAB = Referee(struct 31 | structure Maxie = HumanPlayer(RL2) 32 | structure Minnie = ABFour(RL2) 33 | end) 34 | 35 | 36 | structure Risk_HvJam = Referee(struct 37 | structure Maxie = HumanPlayer(RL2) 38 | structure Minnie = Jam(RL2) 39 | end) 40 | -------------------------------------------------------------------------------- /hw/12/code/treedict.sml: -------------------------------------------------------------------------------- 1 | functor TreeDict (K : ORDERED) : DICT = 2 | struct 3 | 4 | structure Key = K 5 | 6 | (* Invariant: BST *) 7 | datatype ('k, 'v) tree = 8 | Leaf 9 | | Node of ('k, 'v) tree * ('k * 'v) * ('k, 'v) tree 10 | 11 | type 'v dict = (Key.t, 'v) tree 12 | 13 | val empty = Leaf 14 | 15 | fun insert d (k, v) = 16 | case d of 17 | Leaf => Node (empty, (k, v), empty) 18 | | Node (L, (k', v'), R) => 19 | case Key.compare (k, k') of 20 | EQUAL => Node (L, (k, v), R) 21 | | LESS => Node (insert L (k, v), (k', v'), R) 22 | | GREATER => Node (L, (k', v'), insert R (k, v)) 23 | 24 | fun lookup d k = 25 | case d of 26 | Leaf => NONE 27 | | Node (L, (k', v'), R) => 28 | case Key.compare (k, k') of 29 | EQUAL => SOME v' 30 | | LESS => lookup L k 31 | | GREATER => lookup R k 32 | local 33 | fun rightmost (T : ('k, 'v) tree) : (('k * 'v) * ('k, 'v) tree) option = 34 | case T of 35 | Leaf => NONE 36 | | Node (L, (k, v), R) => 37 | case rightmost R of 38 | NONE => SOME ((k, v), L) 39 | | SOME (p, R') => SOME (p, Node (L, (k, v), R')) 40 | in 41 | fun remove d k = 42 | case d of 43 | Leaf => Leaf 44 | | Node (L, (k', v'), R) => 45 | (case Key.compare (k, k') of 46 | EQUAL => 47 | (case rightmost L of 48 | NONE => R 49 | | SOME ((kr, vr), L') => Node (L', (kr, vr), R)) 50 | | LESS => Node (remove L k, (k', v'), R) 51 | | GREATER => Node (L, (k', v'), remove R k)) 52 | end 53 | 54 | end 55 | -------------------------------------------------------------------------------- /lab/10/code/dict.sml: -------------------------------------------------------------------------------- 1 | functor Dict (K : EQUAL) : DICT = 2 | struct 3 | structure K : EQUAL = K 4 | type 'a dict = (K.t*'a) list 5 | type key = K.t 6 | 7 | fun size (d : 'a dict) : int = List.length d 8 | 9 | fun find (d : 'a dict) (k : key) : 'a option = 10 | case d of 11 | [] => NONE 12 | | (k1,v1)::ds => if K.equal(k1,k) then SOME v1 else 13 | find ds k 14 | 15 | fun insert (f : 'a*'a -> 'a) (k : key, v : 'a) (d : 'a dict) : 'a dict = 16 | case d of 17 | [] => [(k,v)] 18 | | (k1,v1)::xs => if K.equal(k1,k) then (k,f(v1,v))::xs 19 | else (k1,v1)::(insert f (k,v) xs) 20 | 21 | fun delete (k : key) (d : 'a dict) : 'a dict = 22 | case d of 23 | [] => [] 24 | | (k1,v1)::xs => if K.equal(k1,k) then xs 25 | else (k1,v1)::delete k xs 26 | 27 | 28 | fun empty () = [] 29 | 30 | fun singleton (k : key, v : 'a) : 'a dict = [(k, v)] 31 | 32 | fun map (f : 'a -> 'b) (d : 'a dict) : 'b dict = 33 | List.map (fn (k,v) => (k,f v)) d 34 | 35 | fun filter (f : 'a -> bool) (d : 'a dict) : 'a dict = 36 | List.filter (fn (k,v) => f v) d 37 | 38 | fun filterk (f : key -> bool) (d : 'a dict) : 'a dict = 39 | List.filter (fn (k,v) => f k) d 40 | 41 | 42 | fun merge (f : 'a*'a -> 'a) (d1 : 'a dict, d2 : 'a dict) : 'a dict = 43 | let 44 | val d2' = List.filter 45 | (fn (k,v) => case find d1 k of NONE => true | _ => false) d2 46 | val d1' = List.map (fn (k,v) => 47 | case find d2 k of 48 | NONE => (k,v) 49 | | SOME v' => (k,f(v,v'))) d1 50 | in 51 | d1'@d2' 52 | end 53 | 54 | fun toList (d : 'a dict) : (key * 'a) list = d 55 | 56 | fun fromList (L : (key * 'a) list) : 'a dict = L 57 | 58 | end 59 | -------------------------------------------------------------------------------- /lab/09/solutions/code/ListSets.sml: -------------------------------------------------------------------------------- 1 | structure ListSets : INTSET = 2 | struct 3 | exception NotYetImplemented 4 | exception NotInSet 5 | 6 | type set = int list 7 | 8 | val empty = fn () => [] 9 | 10 | fun find (n : int) (s : set) = 11 | case s of 12 | [] => false 13 | | x :: l => (x = n) orelse (find n l) 14 | 15 | (* in this version, we allow you to keep duplicates when inserting *) 16 | fun insert (n : int) (s : set) = n :: s 17 | 18 | (* you must delete all duplicates in this *) 19 | (* also should handle the case in which n is not in the set *) 20 | fun delete (n : int) (s : set) = 21 | case find n s of 22 | false => raise NotInSet 23 | | _ => List.filter (fn x => not (x = n)) s 24 | 25 | (* union is also allowed to have duplicates in it *) 26 | fun union (s1 : set) (s2 : set) = 27 | s1@s2 28 | 29 | (* all elements in s1 and s2 *) 30 | fun intersection (s1 : set) (s2 : set) = 31 | case (s1, s2) of 32 | ([],_) => [] 33 | | (_,[]) => [] 34 | | (_,_) => List.filter (fn x => find x s2) s1 35 | 36 | 37 | (* s1 - s2 *) 38 | (* Note - we're removing all instances of the duplicate *) 39 | fun difference (s1 : set) (s2 : set) = 40 | case (s1, s2) of 41 | ([], _) => [] 42 | | (_,[]) => s1 43 | | (_,_) => List.filter (fn x => not(find x s2)) s1 44 | 45 | end 46 | 47 | structure TestListSets = 48 | struct 49 | (* Note that we have to use 'ListSets.find' rather than 'find', 50 | * since we're in a different structure. 51 | *) 52 | val true = ListSets.find 1 [1,2,3] 53 | val [1,1,2] = ListSets.insert 1 [1,2] 54 | val [2] = ListSets.delete 1 [1,1,2] 55 | val [1,2,3,4] = ListSets.union [1,2] [3,4] 56 | val [1,2] = ListSets.intersection [1,2,3,4] [5,6,1,2] 57 | val [1,2] = ListSets.difference [1,2,3,4] [3,4] 58 | end 59 | -------------------------------------------------------------------------------- /hw/10/bobbfile.py: -------------------------------------------------------------------------------- 1 | import os.path 2 | 3 | import config 4 | 5 | from bobb.registrars import builder, action 6 | from bobb.operations import run, cd, abort, log 7 | 8 | this_dir = os.path.abspath(__file__) 9 | if not os.path.isdir(this_dir): 10 | this_dir = os.path.abspath(os.path.join(this_dir, '..')) 11 | 12 | @builder( 13 | dir=this_dir, 14 | tgts=['handin.tgz'], 15 | deps=config.handin_files 16 | ) 17 | def build_handin_tgz(): 18 | run('tar cvzf handin.tgz %s' % ' '.join(config.handin_files)) 19 | 20 | @action( 21 | dir=this_dir, 22 | deps=['handin.tgz'] 23 | ) 24 | def package(): 25 | pass 26 | 27 | @action( 28 | dir=this_dir, 29 | deps=['handin.tgz'] 30 | ) 31 | def submit(): 32 | user = run('whoami') 33 | assessment = config.lab_name 34 | destination = run('wget -q -O- "http://unofficial.fish.ics.cs.cmu.edu/officialSubmit.rb?' + 35 | 'course=15150-f13&user=%s&assessment=%s"' % (user, assessment)) 36 | run('cp handin.tgz %s' % destination) 37 | out = run('wget -q -O- "http://unofficial.fish.ics.cs.cmu.edu/officialSubmit.rb?' + 38 | ('course=15150-f13&user=%s&assessment=%s&submit=handin.tgz" | ' % (user, assessment)) + 39 | 'grep "Submission received"', check_retval=False) 40 | 41 | if out.return_code == 0: 42 | log('Submission received. Please verify your score on Autolab.') 43 | else: 44 | abort('Submission NOT received. Contact a TA.') 45 | 46 | @action( 47 | dir=this_dir, 48 | deps=['sources.cm'] 49 | ) 50 | def compile(): 51 | runner = \ 52 | ('val _ =\n' 53 | ' if CM.make "sources.cm"\n' 54 | ' then OS.Process.exit(OS.Process.success)\n' 55 | ' else OS.Process.exit(OS.Process.failure)') 56 | 57 | f = open('compile.sml', 'w') 58 | f.write(runner) 59 | f.close() 60 | 61 | out = run('sml -m compile.sml', check_retval=False) 62 | run('rm compile.sml') 63 | 64 | if out.return_code != 0: 65 | abort('Your code does not compile cleanly!') 66 | -------------------------------------------------------------------------------- /hw/11/bobbfile.py: -------------------------------------------------------------------------------- 1 | import os.path 2 | 3 | import config 4 | 5 | from bobb.registrars import builder, action 6 | from bobb.operations import run, cd, abort, log 7 | 8 | this_dir = os.path.abspath(__file__) 9 | if not os.path.isdir(this_dir): 10 | this_dir = os.path.abspath(os.path.join(this_dir, '..')) 11 | 12 | @builder( 13 | dir=this_dir, 14 | tgts=['handin.tgz'], 15 | deps=config.handin_files 16 | ) 17 | def build_handin_tgz(): 18 | run('tar cvzf handin.tgz %s' % ' '.join(config.handin_files)) 19 | 20 | @action( 21 | dir=this_dir, 22 | deps=['handin.tgz'] 23 | ) 24 | def package(): 25 | pass 26 | 27 | @action( 28 | dir=this_dir, 29 | deps=['handin.tgz'] 30 | ) 31 | def submit(): 32 | user = run('whoami') 33 | assessment = config.lab_name 34 | destination = run('wget -q -O- "http://unofficial.fish.ics.cs.cmu.edu/officialSubmit.rb?' + 35 | 'course=15150-f13&user=%s&assessment=%s"' % (user, assessment)) 36 | run('cp handin.tgz %s' % destination) 37 | out = run('wget -q -O- "http://unofficial.fish.ics.cs.cmu.edu/officialSubmit.rb?' + 38 | ('course=15150-f13&user=%s&assessment=%s&submit=handin.tgz" | ' % (user, assessment)) + 39 | 'grep "Submission received"', check_retval=False) 40 | 41 | if out.return_code == 0: 42 | log('Submission received. Please verify your score on Autolab.') 43 | else: 44 | abort('Submission NOT received. Contact a TA.') 45 | 46 | @action( 47 | dir=this_dir, 48 | deps=['sources.cm'] 49 | ) 50 | def compile(): 51 | runner = \ 52 | ('val _ =\n' 53 | ' if CM.make "sources.cm"\n' 54 | ' then OS.Process.exit(OS.Process.success)\n' 55 | ' else OS.Process.exit(OS.Process.failure)') 56 | 57 | f = open('compile.sml', 'w') 58 | f.write(runner) 59 | f.close() 60 | 61 | out = run('sml -m compile.sml', check_retval=False) 62 | run('rm compile.sml') 63 | 64 | if out.return_code != 0: 65 | abort('Your code does not compile cleanly!') 66 | -------------------------------------------------------------------------------- /hw/12/bobbfile.py: -------------------------------------------------------------------------------- 1 | import os.path 2 | 3 | import config 4 | 5 | from bobb.registrars import builder, action 6 | from bobb.operations import run, cd, abort, log 7 | 8 | this_dir = os.path.abspath(__file__) 9 | if not os.path.isdir(this_dir): 10 | this_dir = os.path.abspath(os.path.join(this_dir, '..')) 11 | 12 | @builder( 13 | dir=this_dir, 14 | tgts=['handin.tgz'], 15 | deps=config.handin_files 16 | ) 17 | def build_handin_tgz(): 18 | run('tar cvzf handin.tgz %s' % ' '.join(config.handin_files)) 19 | 20 | @action( 21 | dir=this_dir, 22 | deps=['handin.tgz'] 23 | ) 24 | def package(): 25 | pass 26 | 27 | @action( 28 | dir=this_dir, 29 | deps=['handin.tgz'] 30 | ) 31 | def submit(): 32 | user = run('whoami') 33 | assessment = config.lab_name 34 | destination = run('wget -q -O- "http://unofficial.fish.ics.cs.cmu.edu/officialSubmit.rb?' + 35 | 'course=15150-f13&user=%s&assessment=%s"' % (user, assessment)) 36 | run('cp handin.tgz %s' % destination) 37 | out = run('wget -q -O- "http://unofficial.fish.ics.cs.cmu.edu/officialSubmit.rb?' + 38 | ('course=15150-f13&user=%s&assessment=%s&submit=handin.tgz" | ' % (user, assessment)) + 39 | 'grep "Submission received"', check_retval=False) 40 | 41 | if out.return_code == 0: 42 | log('Submission received. Please verify your score on Autolab.') 43 | else: 44 | abort('Submission NOT received. Contact a TA.') 45 | 46 | @action( 47 | dir=this_dir, 48 | deps=['sources.cm'] 49 | ) 50 | def compile(): 51 | runner = \ 52 | ('val _ =\n' 53 | ' if CM.make "sources.cm"\n' 54 | ' then OS.Process.exit(OS.Process.success)\n' 55 | ' else OS.Process.exit(OS.Process.failure)') 56 | 57 | f = open('compile.sml', 'w') 58 | f.write(runner) 59 | f.close() 60 | 61 | out = run('sml -m compile.sml', check_retval=False) 62 | run('rm compile.sml') 63 | 64 | if out.return_code != 0: 65 | abort('Your code does not compile cleanly!') 66 | -------------------------------------------------------------------------------- /hw/10/code/lib/space.sig: -------------------------------------------------------------------------------- 1 | (* scalars and operations on them *) 2 | signature SPACE = 3 | sig 4 | structure Scalar : SCALAR 5 | structure Seq : SEQUENCE 6 | 7 | type scalar = Scalar.scalar 8 | 9 | (* points and vectors and operations on them *) 10 | type point 11 | type vec 12 | 13 | (* v1 ++ v2 evaluates to the sum of the vectors *) 14 | val ++ : vec * vec -> vec 15 | 16 | (* v ** c evaluates to the scalar product of v with c *) 17 | val ** : vec * scalar -> vec 18 | 19 | (* X --> Y is the vector from X to Y *) 20 | val --> : point * point -> vec 21 | 22 | (* v // c evaluates to the scalar product of v with (1/c) *) 23 | val // : vec * scalar -> vec 24 | 25 | (* the center of the plane *) 26 | val origin : point 27 | 28 | (* Computes the distance between the argument points *) 29 | val distance : point -> point -> scalar 30 | 31 | (* Computes the magnitude of the given vector *) 32 | val mag : vec -> scalar 33 | 34 | val vecToString : vec -> string 35 | val pointToString : point -> string 36 | 37 | (* equality of points *) 38 | val pointEqual : point * point -> bool 39 | 40 | (* displace a point by a vector *) 41 | val displace : point * vec -> point 42 | 43 | (* the head of a vector as a point in the plane *) 44 | val head : vec -> point 45 | 46 | (* given a vector in a direction, produces the unit vec in that direction *) 47 | val unitVec : vec -> vec 48 | 49 | (* the zero vector *) 50 | val zero : vec 51 | 52 | 53 | (* given two points, gives the point at the middle of the line between them *) 54 | val midpoint : point -> point -> point 55 | 56 | (* sums up a bunch of vectors when you give it a function that tells 57 | * how to make a vector from a value of type 'a *) 58 | val sum : ('a -> vec) -> 'a Seq.seq -> vec 59 | 60 | (* do NOT use these two functions except for testing *) 61 | val cartcoord : point -> scalar * scalar 62 | val fromcoord : scalar * scalar -> point 63 | end 64 | -------------------------------------------------------------------------------- /hw/11/code/referee.sml: -------------------------------------------------------------------------------- 1 | signature TWO_PLAYERS = 2 | sig 3 | structure Maxie : PLAYER 4 | structure Minnie : PLAYER 5 | sharing type Maxie.Game.state = Minnie.Game.state 6 | sharing type Maxie.Game.move = Minnie.Game.move 7 | end 8 | 9 | functor Referee (P : TWO_PLAYERS) : sig val go : unit -> unit end = 10 | struct 11 | structure Game = P.Maxie.Game 12 | 13 | fun outcomeToString Game.Draw = Game.Est.toString Game.Est.draw 14 | | outcomeToString (Game.Winner (Game.Minnie)) = 15 | Game.Est.toString Game.Est.minnie_wins 16 | | outcomeToString (Game.Winner (Game.Maxie)) = 17 | Game.Est.toString Game.Est.maxie_wins 18 | fun play state = 19 | case Game.status state of 20 | Game.Over outcome => 21 | let val () = print ((Game.state_to_string state) ^ "\n") 22 | val () = print ("Game over! " ^ outcomeToString outcome ^ "\n") 23 | in 24 | () 25 | end 26 | | Game.In_play => 27 | let 28 | val () = print ((Game.state_to_string state) ^ "\n") 29 | val t0 = Time.now () 30 | val move = 31 | case Game.player state of 32 | Game.Maxie => P.Maxie.next_move state 33 | | Game.Minnie => P.Minnie.next_move state 34 | val t1 = Time.now () 35 | 36 | val () = print ((case Game.player state of 37 | Game.Maxie => "Maxie" 38 | | Game.Minnie => "Minnie") 39 | ^ " decides to make the move " 40 | ^ (Game.move_to_string move) 41 | ^ " in " ^ 42 | IntInf.toString(Time.toSeconds(Time.-(t1,t0))) ^ 43 | " seconds.\n") 44 | in 45 | play (Game.make_move (state,move)) 46 | end 47 | 48 | 49 | fun go () = play (Game.start) 50 | end 51 | 52 | -------------------------------------------------------------------------------- /lab/10/solutions/rbtree.sml: -------------------------------------------------------------------------------- 1 | structure RbTree= 2 | struct 3 | 4 | exception Unimplemented 5 | 6 | (* A possible implementation of RBTs for keys as integers *) 7 | type key = int 8 | val compare : key * key -> order = Int.compare 9 | datatype color = Red | Black 10 | datatype 'v rbtree = Empty 11 | | Node of 'v rbtree * (color * (key * 'v)) * 'v rbtree 12 | 13 | (* Task 3.1 *) 14 | fun blackdepth Empty = 0 15 | | blackdepth (Node(l, (c, _), r)) = if (c=Black) then 16 | Int.max(blackdepth l, blackdepth r) + 1 17 | else Int.max(blackdepth l, blackdepth r) 18 | 19 | fun isRBT Empty = true 20 | | isRBT (Node(Empty, _, Empty)) = true 21 | | isRBT (Node(l, (c, (k, _)), Empty)) = 22 | let val (Node(_, (lc, (lk, _)), _)) = l 23 | in if (c = Red andalso lc = Red) then false 24 | else (blackdepth(l) = 0) 25 | end 26 | | isRBT (Node(Empty, (c, (k, _)), r)) = 27 | let val (Node(_, (rc, (rk, _)), _)) = r 28 | in if (c = Red andalso rc = Red) then false 29 | else (blackdepth(r) = 0) 30 | end 31 | | isRBT (Node(l, (c, (k,_)), r)) = 32 | let val (Node(_, (lc, (lk, _)), _)) = l 33 | val (Node(_, (rc, (rk, _)), _)) = r 34 | in if (c = Red andalso (lc = Red orelse rc = Red)) then false 35 | else (blackdepth(l) = blackdepth(r) andalso 36 | isRBT(l) andalso isRBT(r)) 37 | end 38 | 39 | val e = Empty 40 | val t1 = Node(e,(Red, (3, 3)),e) 41 | val t2 = Node(t1,(Red, (4,10)), e) 42 | val t3 = Node(e,(Red, (63,23)), t1) 43 | val t4 = Node(t1,(Black, (10, 3289)), e) 44 | val t5 = Node(e,(Black, (43,234)),e) 45 | val t6 = Node(t5,(Red, (4,234)), e) 46 | val t7 = Node(e,(Red, (16,234)), t5) 47 | val t8 = Node(t4, (Black, (11,12)), t5) 48 | val t9 = Node(t4, (Black, (11,12)), t7) 49 | val true = isRBT(e) 50 | val true = isRBT(t1) 51 | val false = isRBT(t2) (* well-red *) 52 | val false = isRBT(t3) (* ordering *) 53 | val true = isRBT(t4) 54 | val true = isRBT(t5) 55 | val false = isRBT(t6) (* ordering *) 56 | val false = isRBT(t7) (* black-depth *) 57 | val true = isRBT(t8) 58 | val false = isRBT(t9) (* black-depth *) 59 | 60 | end 61 | -------------------------------------------------------------------------------- /hw/10/code/rat.system.1day.auto.txt: -------------------------------------------------------------------------------- 1 | 2 | (0, 0),(0, 57909100000),(0, ~108208930000),(0, ~149600000000),(0, 227939100000),(0, 778547200000),(0, ~1433449370000),(0, 2876679082000),(0, ~4503443661000) 3 | (0, 89672306950407643430583101766120980391872037099462165695074727093304658386781050763605261078293430444305684683677/769063620204064098523290039836889610094532906404642905981399651526036065793403951861379776320331703708016720),(41359680000, 16843568698634729433407380257377586804148262945087692709245113656414933753430263281880101618911005472386166112/593932801089660957766323513354587118091078539531890477413736490106673185956923045533830220172625625),(~30257280000, ~34278444942808596531283685750465683867392088369127464429777579473792047562629451141068188301396141961835589736552128057021563927593040/343657255516888148758601873090525355777017627791460983468484332575052288902818177852965981951372346958381914114346192417049),(~25729920000, ~971499214160614526555342194091066459324290182244323509338891081768361925771782623675306403803602019394174000154448/6692057109604636804340791017055818789576799189707006844287011229002008084862255125108973649270689474435),(20802528000, 18837872003554879948495502573316419418523654168340782297434857904773858681498609330170380997883148996186915854610912/83341567399582726344290344473085809585667299413362790986070572645319537510171035699459785165023562903125),(11292480000, 125153855022061063650478779838736204354181606278951249395171898041585145417712425835929211180512/160786837663293965987963333116360042220651105229947139276192862355302790447505518405),(~8372160000, ~356415558290106191501713863885695737446136804130387230155578458990855831100256193517130492580657040/248650257246059651017611384575681013340824373346899564438909519671854112278332683117409),(5883840000, 417369740609169076393215276295511209863535878570487525124223827842056601547647134922000/145087953471547342346667139127617014767100150908902298404151921770428832849),(~4691520000, ~37936002007286560609764484364434324234928162743175251873304843237862482528958905750077965000/8423785457110075009655030277984869530219382785676046155612242871872300370599489) 4 | -------------------------------------------------------------------------------- /hw/10/code/tests/rat.system.1day.auto.txt: -------------------------------------------------------------------------------- 1 | 2 | (0, 0),(0, 57909100000),(0, ~108208930000),(0, ~149600000000),(0, 227939100000),(0, 778547200000),(0, ~1433449370000),(0, 2876679082000),(0, ~4503443661000) 3 | (0, 89672306950407643430583101766120980391872037099462165695074727093304658386781050763605261078293430444305684683677/769063620204064098523290039836889610094532906404642905981399651526036065793403951861379776320331703708016720),(41359680000, 16843568698634729433407380257377586804148262945087692709245113656414933753430263281880101618911005472386166112/593932801089660957766323513354587118091078539531890477413736490106673185956923045533830220172625625),(~30257280000, ~34278444942808596531283685750465683867392088369127464429777579473792047562629451141068188301396141961835589736552128057021563927593040/343657255516888148758601873090525355777017627791460983468484332575052288902818177852965981951372346958381914114346192417049),(~25729920000, ~971499214160614526555342194091066459324290182244323509338891081768361925771782623675306403803602019394174000154448/6692057109604636804340791017055818789576799189707006844287011229002008084862255125108973649270689474435),(20802528000, 18837872003554879948495502573316419418523654168340782297434857904773858681498609330170380997883148996186915854610912/83341567399582726344290344473085809585667299413362790986070572645319537510171035699459785165023562903125),(11292480000, 125153855022061063650478779838736204354181606278951249395171898041585145417712425835929211180512/160786837663293965987963333116360042220651105229947139276192862355302790447505518405),(~8372160000, ~356415558290106191501713863885695737446136804130387230155578458990855831100256193517130492580657040/248650257246059651017611384575681013340824373346899564438909519671854112278332683117409),(5883840000, 417369740609169076393215276295511209863535878570487525124223827842056601547647134922000/145087953471547342346667139127617014767100150908902298404151921770428832849),(~4691520000, ~37936002007286560609764484364434324234928162743175251873304843237862482528958905750077965000/8423785457110075009655030277984869530219382785676046155612242871872300370599489) 4 | -------------------------------------------------------------------------------- /hw/10/code/sizeseq.sml: -------------------------------------------------------------------------------- 1 | structure SizeSeq : TSEQ = 2 | struct 3 | (* remove this when you are done *) 4 | exception Unimplemented 5 | 6 | datatype 'a sseq = Empty 7 | | Leaf of 'a 8 | | Node of 'a sseq * int * 'a sseq 9 | 10 | type 'a seq = 'a sseq 11 | exception Range 12 | 13 | (* length : 'a seq -> int *) 14 | (* REQUIRES : true *) 15 | (* ENSURES : length S evaluates to the length of S *) 16 | fun length Empty = 0 17 | | length (Leaf _) = 1 18 | | length (Node(L,s,R)) = s 19 | 20 | (* nth : int -> 'a seq -> 'a *) 21 | (* REQUIRES : true *) 22 | (* ENSURES : nth i s evaluates to the ith item in S *) 23 | fun nth i Empty = raise Range 24 | | nth 0 (Leaf x) = x 25 | | nth i (Leaf x) = raise Range 26 | | nth i (Node(L,s,R)) = 27 | let 28 | val lenL = length L 29 | val lenR = length R 30 | in 31 | case (Int.compare(i, lenL + lenR), Int.compare(i, lenL)) of 32 | (LESS, LESS) => nth i L 33 | | (LESS, _) => nth (i - lenL) R 34 | | _ => raise Range 35 | end 36 | 37 | (* tabulate : int -> 'a seq -> 'a *) 38 | (* REQUIRES : n >= 0 *) 39 | (* ENSURES : Seq.tabulate f n evaluates to a sequence s with length n 40 | * where the ith item of s is the result of evaluating (f i) *) 41 | fun tabulate f 0 = Empty 42 | | tabulate f 1 = Leaf(f 0) 43 | | tabulate f n = 44 | Node(tabulate f (n div 2), n, 45 | tabulate (fn x => f (x + (n div 2))) (n - (n div 2))) 46 | 47 | end 48 | 49 | 50 | structure TestSizeSeq = 51 | struct 52 | open SizeSeq 53 | 54 | (*Tests for ShrubSeq *) 55 | val ShrubOne = tabulate (fn x => x) 8 56 | val ShrubTwo = tabulate (fn x => 2*x) 7 57 | val ShrubThree = tabulate (fn x => ~x - 5) 1 58 | val ShrubFour = tabulate (fn x => x) 0 59 | val 8 = length ShrubOne 60 | val 7 = length ShrubTwo 61 | val 1 = length ShrubThree 62 | val 0 = length ShrubFour 63 | val 2 = nth 2 ShrubOne 64 | val 12 = nth 6 ShrubTwo 65 | val ~5 = nth 0 ShrubThree 66 | 67 | end 68 | -------------------------------------------------------------------------------- /lab/09/code/TreeSets.sml: -------------------------------------------------------------------------------- 1 | structure TreeSets : INTSET = 2 | struct 3 | exception NotYetImplemented 4 | exception IntentionallyUnimplemented 5 | 6 | exception NotInSet 7 | 8 | datatype 'a tree = Empty | Node of 'a tree * 'a * 'a tree 9 | 10 | type set = int tree 11 | 12 | val empty = fn () => Empty 13 | 14 | fun find (n : int) (Empty : set) = false 15 | | find (n : int) (Node(l,x,r) : set) = 16 | if (n = x) 17 | then true 18 | else (find n l) orelse (find n r) 19 | 20 | fun insert (n : int) (s : set) = Node(s, n, Empty) 21 | 22 | (* delete : int -> set -> set 23 | * requires: true 24 | * ensures: raises IntentiallyUnimplemented 25 | * 26 | * You don't have to implement delete; though once you learn mutually recursive 27 | * functions, you'll be able to. 28 | * 29 | * Luckily, you can write union, intersection, and difference without delete! 30 | *) 31 | fun delete (n : int) (s : set) = raise IntentionallyUnimplemented 32 | 33 | fun union (Empty : set) (s2 : set) = s2 34 | | union (s1 : set) (Empty : set) = s1 35 | | union (Node(l,x,r) : set) (s2 : set) = Node(l,x,(union r s2)) 36 | 37 | fun intersection (Empty : set) (s2 : set) = Empty 38 | | intersection (s1 : set) (Empty : set) = Empty 39 | | intersection (Node(l,x,r) : set) (s2 : set) = 40 | if (find x s2) 41 | then Node((intersection l s2),x,(intersection r s2)) 42 | else union (intersection l s2) (intersection r s2) 43 | 44 | fun difference (Empty : set) (s2 : set) = Empty 45 | | difference (s1 : set) (Empty : set) = Empty 46 | | difference (Node(l,x,r) : set) (s2 : set) = 47 | if (find x s2) 48 | then union (difference l s2) (difference r s2) 49 | else Node((difference l s2),x,(difference r s2)) 50 | 51 | end 52 | 53 | structure TestTreeSets = 54 | struct 55 | (* 'open' brings everything in the TreeSet namespace into this structure. 56 | * We can now use 'insert' instead of 'TreeSets.insert' 57 | *) 58 | open TreeSets 59 | 60 | (* t = <5, 6> *) 61 | val t = empty() 62 | val t = insert 5 t 63 | val true = find 5 t 64 | 65 | (* Your tests here! *) 66 | 67 | end 68 | -------------------------------------------------------------------------------- /lab/01/solutions/code/lab01-sol.sml: -------------------------------------------------------------------------------- 1 | (* ---------------------------------------------------------------------- *) 2 | (* For Sec 7.1 *) 3 | fun intToString (x : int) : string = Int.toString x 4 | (* ---------------------------------------------------------------------- *) 5 | 6 | (* ---------------------------------------------------------------------- *) 7 | 8 | (* Code from class *) 9 | 10 | (* sum : int list -> int*) 11 | (* REQUIRES: true*) 12 | (* ENSURES: sum(L) evaluates to the sum of the integers in L.*) 13 | fun sum ([ ] : int list) : int = 0 14 | | sum (x::L) = x + (sum L); 15 | 16 | (* count : int list list -> int*) 17 | (* REQUIRES: true*) 18 | (* ENSURES: count(R) evaluates to the sum of the integers in R.*) 19 | fun count ([ ] : int list list) : int = 0 20 | | count (r::R) = (sum r) + (count R) 21 | 22 | (*Task 7.2*) 23 | (*mult: int list -> int*) 24 | (*REQUIRES: true*) 25 | (*ENSURES: mult(L) evaluates to the product of integers in L*) 26 | fun mult ([] : int list) = 1 27 | | mult (x :: L) = x * mult(L) 28 | 29 | val 1 = mult [] 30 | val 5 = mult [5] 31 | val 42 = mult [2, 21] 32 | 33 | (*Task 7.3*) 34 | (*mult' : int list * int -> int*) 35 | (*REQUIRES: true*) 36 | (*ENSURES: mult'(L, a) evaluates to the product of integers in L times a*) 37 | fun mult' ([] : int list, a : int) : int = a 38 | | mult' (x::L, a) = mult'(L, x * a) 39 | 40 | val 10 = mult' ([], 10) 41 | val 3 = mult' ([3], 1) 42 | val 60 = mult' ([2, 1, 15], 2) 43 | 44 | (*Task 7.4*) 45 | (*Mult : int list list -> int*) 46 | (*REQUIRES: true*) 47 | (*ENSURES: Mult(R) evaluates to the product of integers in R*) 48 | 49 | fun Mult ([] : int list list) : int = 1 50 | | Mult (r :: R) = (mult r) * (Mult R) 51 | 52 | val 1 = Mult [] 53 | val 1 = Mult [[]] 54 | val 10 = Mult [[10]] 55 | val 35 = Mult [[7, 5]] 56 | val 21 = Mult [[1, 3], [7]] 57 | 58 | (*Task 7.5*) 59 | (*Mult : int list list * int -> int*) 60 | (*REQUIRES: True*) 61 | (*ENSURES: Mult (R, a) evaluates to the product of integers in R times a*) 62 | 63 | fun Mult' ([] : int list list, a : int) = a 64 | | Mult' (r::R, a) = Mult' (R, mult' (r, 1) * a) 65 | 66 | val 5 = Mult' ([], 5) 67 | val ~16 = Mult' ([[~4]], 4) 68 | val 180 = Mult' ([[2, 2, ~1], [15, ~1], [3]], 1) 69 | -------------------------------------------------------------------------------- /hw/10/code/shrubseq.sml: -------------------------------------------------------------------------------- 1 | structure ShrubSeq : TSEQ = 2 | struct 3 | (* remove this line when you are done *) 4 | exception Unimplemented 5 | 6 | datatype 'a sseq = Empty 7 | | Leaf of 'a 8 | | Node of 'a sseq * 'a sseq 9 | 10 | type 'a seq = 'a sseq 11 | exception Range 12 | 13 | (* length : 'a seq -> int *) 14 | (* REQUIRES : true *) 15 | (* ENSURES : length s evaluates to the number of items in S *) 16 | fun length Empty = 0 17 | | length (Leaf _) = 1 18 | | length (Node(L,R)) = length L + length R 19 | 20 | (* nth : int -> 'a seq -> 'a *) 21 | (* REQUIRES : true *) 22 | (* ENSURES : nth i s evaluates to the ith item in S *) 23 | fun nth i Empty = raise Range 24 | | nth 0 (Leaf x) = x 25 | | nth i (Leaf x) = raise Range 26 | | nth i (Node(L,R)) = 27 | if (i >= length (Node(L,R))) 28 | then raise Range 29 | else 30 | let 31 | val lenL = length L 32 | val lenR = length R 33 | in 34 | case (Int.compare(i, lenL + lenR), Int.compare(i, lenL)) of 35 | (LESS, LESS) => nth i L 36 | | (LESS, _) => nth (i - lenL) R 37 | | _ => raise Range 38 | end 39 | 40 | (* tabulate : int -> 'a seq -> 'a *) 41 | (* REQUIRES : n >= 0 *) 42 | (* ENSURES : Seq.tabulate f n evaluates to a sequence s with length n 43 | * where the ith item of s is the result of evaluating (f i) *) 44 | fun tabulate f 0 = Empty 45 | | tabulate f 1 = Leaf(f 0) 46 | | tabulate f n = 47 | Node(tabulate f (n div 2), 48 | tabulate (fn x => f (x + (n div 2))) (n - (n div 2))) 49 | 50 | end 51 | 52 | 53 | structure TestShrubSeq = 54 | struct 55 | open ShrubSeq 56 | 57 | (*Tests for ShrubSeq *) 58 | val ShrubOne = tabulate (fn x => x) 8 59 | val ShrubTwo = tabulate (fn x => 2*x) 7 60 | val ShrubThree = tabulate (fn x => ~x - 5) 1 61 | val ShrubFour = tabulate (fn x => x) 0 62 | val 8 = length ShrubOne 63 | val 7 = length ShrubTwo 64 | val 1 = length ShrubThree 65 | val 0 = length ShrubFour 66 | val 2 = nth 2 ShrubOne 67 | val 12 = nth 6 ShrubTwo 68 | val ~5 = nth 0 ShrubThree 69 | 70 | end 71 | -------------------------------------------------------------------------------- /src/sequence/derivesequence.sml: -------------------------------------------------------------------------------- 1 | functor DeriveSequence (S : SEQUENCECORE) :> SEQUENCE = 2 | struct 3 | open S 4 | 5 | fun mapreduce f b c s = reduce c b (map f s) 6 | handle (Range s) => 7 | raise Range ("mapreduce called with a function that raised Range with \"" 8 | ^ s ^ "\"") 9 | 10 | fun toString eltToString s = 11 | let 12 | fun f (NONE, x) = x 13 | | f (x, NONE) = x 14 | | f (SOME x, SOME y) = SOME (x ^ ", " ^ y) 15 | in 16 | "[" ^ 17 | (case mapreduce (SOME o eltToString) NONE f s 18 | of NONE => "" | SOME s => s) 19 | ^ "]" 20 | end 21 | 22 | fun repeat n x = tabulate (fn _ => x) n 23 | 24 | fun zip (sa, sb) = tabulate (fn n => (nth n sa, nth n sb)) 25 | (Int.min(length sa, length sb)) 26 | 27 | fun append s1 s2 = hidet (Node (s1, s2)) 28 | 29 | fun empty () : 'a seq = hidel Nil 30 | 31 | fun singleton x = hidet (Leaf x) 32 | 33 | (* FIXME: implement using tabulate for better work/span? *) 34 | fun split i s = 35 | case i of 0 => (empty() , s) 36 | | _ => (* i > 0 *) 37 | (case (i,showt s) of 38 | (_,Empty) => raise Range "split can't get more than 0 elements of Empty" 39 | | (1, Leaf x) => (singleton x, empty ()) 40 | | (_, Leaf _) => raise Range "split can't get more than 1 element of a Leaf" 41 | | (_, Node (l,r)) => 42 | let val ls = length l 43 | in case Int.compare (i, ls) 44 | of LESS => let val (ll, lr) = split i l 45 | in (ll, append lr r) 46 | end 47 | | EQUAL => (l, r) 48 | | GREATER => let val (rl, rr) = split (i - ls) r 49 | in (append l rl, rr) 50 | end 51 | end) 52 | 53 | (* FIXME: implement directly for O(i) work ? *) 54 | fun take i s = (fn (x,_) => x) (split i s) 55 | fun drop i s = (fn (_,y) => y) (split i s) 56 | 57 | fun cons x s = hidel (Cons (x,s)) 58 | 59 | (* FIXME: implement with tabulate instead for better work/span? *) 60 | fun flatten ss = reduce (fn (x,y) => append x y) (empty ()) ss 61 | end 62 | -------------------------------------------------------------------------------- /lab/09/code/ListSets.sml: -------------------------------------------------------------------------------- 1 | structure ListSets : INTSET = 2 | struct 3 | exception NotYetImplemented 4 | exception NotInSet 5 | 6 | type set = int list 7 | 8 | val empty = fn () => [] 9 | 10 | fun find (n : int) (s : set) = foldl (fn (x,y) => x orelse y) false (map (fn z => n = z) s) 11 | 12 | fun insert (n : int) (s : set) = n::s 13 | 14 | fun delete (n : int) (s : set) = List.filter (fn x => x <> n) s 15 | 16 | (* union, intersection, and difference must use higher-order functions *) 17 | fun union (s1 : set) (s2 : set) = s1 @ s2 18 | 19 | fun intersection (s1 : set) (s2 : set) = List.filter (fn x => find x s2) s1 20 | 21 | fun difference (s1 : set) (s2 : set) = List.filter (fn x => not(find x s2)) s1 22 | 23 | end 24 | 25 | structure TestListSets = 26 | struct 27 | (* Note that we have to use 'ListSets.find' rather than 'find', 28 | * since we're in a different structure. 29 | *) 30 | val emptySet = ListSets.empty() 31 | val oneFive = ListSets.insert 5 emptySet 32 | val true = ListSets.find 5 oneFive 33 | 34 | (* Your tests here! *) 35 | 36 | (* Tests for find *) 37 | val true = ListSets.find 3 [1,2,3] 38 | val true = ListSets.find 4 [4,5,4] 39 | val false = ListSets.find 4 [3,2,1] 40 | val false = ListSets.find 1 [] 41 | 42 | (* Tests for insert *) 43 | val [1,2,3] = ListSets.insert 1 [2,3] 44 | val [1,1,2,3] = ListSets.insert 1 [1,2,3] 45 | val [4] = ListSets.insert 4 [] 46 | 47 | (* Tests for delete *) 48 | val [1,2] = ListSets.delete 3 [1,2,3] 49 | val [1,2,3] = ListSets.delete 4 [1,2,3] 50 | val [2,3] = ListSets.delete 1 [1,2,3,1] 51 | val [] = ListSets.delete 1 [] 52 | 53 | (* Tests for union *) 54 | val [1,2,3,4,5] = ListSets.union [1,2,3] [4,5] 55 | val [1,2,3,3,4,5] = ListSets.union [1,2,3] [3,4,5] 56 | val [1,2,3] = ListSets.union [1,2,3] [] 57 | 58 | (* Tests for intersection *) 59 | val [] = ListSets.intersection [1,2,3] [4,5] 60 | val [1,2,3] = ListSets.intersection [1,2,3] [1,2,3] 61 | val [3] = ListSets.intersection [1,2,3] [3,4,5] 62 | val [] = ListSets.intersection [1,2,3] [] 63 | 64 | (* Tests for difference *) 65 | val [1,2,3] = ListSets.difference [1,2,3] [4,5] 66 | val [] = ListSets.difference [1,2,3] [1,2,3] 67 | val [1,2] = ListSets.difference [1,2,3] [3,4,5] 68 | val [1,2,3] = ListSets.difference [1,2,3] [] 69 | 70 | end 71 | -------------------------------------------------------------------------------- /hw/10/code/lib/simulation.sml: -------------------------------------------------------------------------------- 1 | functor Simulation (BH : BARNESHUT) = 2 | struct 3 | (*open BH.Mech 4 | structure Seq = BH.Seq*) 5 | open BH.Args.Mech 6 | structure Seq = BH.Args.BB.Seq 7 | 8 | (* t is the timestep *) 9 | fun stepGen (accs : body Seq.seq -> Plane.vec Seq.seq) 10 | (bodies : body Seq.seq , t : Plane.scalar) = 11 | Seq.map (fn (b,a) => stepBody (b,a,t)) 12 | (Seq.zip (bodies, 13 | accs bodies)) 14 | 15 | val bodySeqToString = 16 | String.concatWith "," o 17 | Seq.mapreduce (fn x => [Plane.pointToString (position x)]) [] op@ 18 | 19 | fun compute_coordinates (s : body Seq.seq) (t : Plane.scalar) (niters : int) 20 | (accs : body Seq.seq -> Plane.vec Seq.seq) 21 | : body Seq.seq list = 22 | let fun comp 0 s acc = (s :: acc) 23 | | comp n s acc = 24 | comp (n-1) (stepGen accs (s, t)) (s :: acc) 25 | in rev (comp niters s []) 26 | end 27 | 28 | fun seqFromList l = foldr (fn (x,y) => Seq.cons x y) (Seq.empty ()) l 29 | 30 | (* FIXME: toString for metrics may not be real-formatted. 31 | * Need to standardize on formatting. 32 | *) 33 | fun run (accs : body Seq.seq -> Plane.vec Seq.seq) 34 | (names : string list) 35 | (s : body list) 36 | (t : Plane.scalar) 37 | (niters : int) 38 | (file : string) : unit = 39 | let 40 | open TextIO 41 | val coords = compute_coordinates (seqFromList s) t niters accs 42 | val outfile = TextIO.openOut file 43 | fun pr x = output (outfile, x) 44 | fun prn x = pr (x ^ "\n") 45 | in 46 | (prn (String.concatWith "," names); 47 | List.app (prn o bodySeqToString) coords; 48 | flushOut outfile; 49 | closeOut outfile) 50 | end 51 | 52 | (* Use the quadratic time pairwise computation of acceleration vectors *) 53 | (* we change the prefix so it doesn't clobber the BH transcripts *) 54 | structure Naive = NaiveNBody(struct 55 | open BH.Args 56 | val prefix = "naive" ^ prefix 57 | end) 58 | val runPairwise = run Naive.accelerations [] 59 | 60 | (* Use Barnes Hut algorithm for the computation of acceleration vectors *) 61 | val runBH = run BH.accelerations [] 62 | end 63 | -------------------------------------------------------------------------------- /hw/10/code/lib/solars.sml: -------------------------------------------------------------------------------- 1 | functor Solars (BH : BARNESHUT) = 2 | struct 3 | local 4 | structure Seq = BH.Args.BB.Seq 5 | structure Plane = BH.Args.BB.Plane 6 | structure Mechanics = BH.Args.Mech 7 | 8 | (* rather inefficient. *) 9 | structure II = IntInf 10 | fun pow (f : II.int, 0) = 1 11 | | pow (f, n) = f * pow (f, n-1) 12 | 13 | (* FIXME: uses floating point arithmetic *) 14 | fun digits x = Real.floor (Math.log10 (Real.fromLargeInt (II.abs x))) 15 | 16 | (* parses a pair in "scientific notation" into a Plane.scalar 17 | * eg sci (412, 13) == 4.12E13 18 | *) 19 | fun sci (0, _) = Plane.Scalar.zero 20 | | sci (f : II.int, exp : int) = 21 | let 22 | val digs = digits f 23 | val f = Plane.Scalar.fromRatio (f, pow (10, digs)) 24 | val order = Plane.Scalar.pow (Plane.Scalar.fromInt 10, exp) 25 | in 26 | Plane.Scalar.times (f, order) 27 | end 28 | 29 | val zero : II.int * int = (0,0) 30 | 31 | fun I x = (x, digits x) 32 | 33 | fun b (mass : II.int * int) (dist : II.int * int) (vel : II.int * int) = 34 | (sci mass, 35 | Plane.fromcoord (Plane.Scalar.zero, sci dist), 36 | Plane.--> (Plane.origin, Plane.fromcoord (sci vel, Plane.Scalar.zero))) 37 | in 38 | (* astronomical constants sourced from Wikipedia, the font of all knowledge *) 39 | 40 | val sun = b (198892, 30) zero zero (* sun *) 41 | val mercury = b (33022, 23) (579091, 10) (I 47870) (* mercury *) 42 | val venus = b (48685, 24) (~10820893, 11) (I ~35020) (* venus *) 43 | val earth = b (59736, 24) (~14960, 11) (I ~29780) (* earth *) 44 | val mars = b (64185, 23) (2279391, 11) (I 24077) (* mars *) 45 | val jupiter = b (18986, 27) (7785472, 11) (I 13070) (* jupiter *) 46 | val saturn = b (56846, 26) (~143344937, 12) (~969, 3) (* saturn *) 47 | val uranus = b (8681, 25) (2876679082, 12) (681, 3) (* uranus *) 48 | val neptune = b (10243, 26) (~4503443661, 12) (~543, 3) (* neptune *) 49 | 50 | val sun2 = b (198892, 30) (7785472, 11) (I 13070) 51 | end 52 | 53 | val one_body = [sun] 54 | val two_body = [sun, earth] 55 | val solar_system = 56 | [sun, mercury, venus, earth, mars, jupiter, saturn, uranus, neptune] 57 | 58 | (* TODO: add more complex systems for interesting visualization *) 59 | end 60 | -------------------------------------------------------------------------------- /hw/12/code/countingdict.sml: -------------------------------------------------------------------------------- 1 | functor AddCounting (D : DICT) : COUNTING_DICT = 2 | struct 3 | 4 | structure Key : ORDERED = D.Key 5 | 6 | (* Change this type as necessary *) 7 | type 'a dict = 'a D.dict * (int ref) D.dict 8 | 9 | (* build : (Key.t * 'a) list -> 'a dict *) 10 | (* REQUIRES: true *) 11 | (* ENSURES: Builds a counting dictionary by inserting a list of key-value 12 | * pairs into an initially empty dictionary *) 13 | fun build ([] : (Key.t * 'a) list) : 'a dict = (D.empty, D.empty) 14 | | build ((k,v)::L : (Key.t * 'a) list) : 'a dict = 15 | let 16 | val (d1,d2) = build(L) 17 | in 18 | (D.insert d1 (k,v), D.insert d2 (k, ref 0)) 19 | end 20 | 21 | (* lookup : 'a dict -> Key.t -> 'a option *) 22 | (* REQUIRES: true *) 23 | (* ENSURES: lookup d k looks up the key k in the dictionary d *) 24 | fun lookup ((d1,d2) : 'a dict) (k : Key.t) : 'a option = 25 | let 26 | val _ = case (D.lookup d2 k) of 27 | SOME(v) => v := !v + 1 28 | | _ => () 29 | in 30 | D.lookup d1 k 31 | end 32 | 33 | (* hits : 'a dict -> Key.t -> int *) 34 | (* REQUIRES: true *) 35 | (* ENSURES: hits d k evaluates to the number of times the key k has been 36 | * successfully looked up in the dictionary d *) 37 | fun hits ((d1,d2) : 'a dict) (k : Key.t) : int = 38 | let 39 | val SOME(v) = D.lookup d2 k 40 | in 41 | !v 42 | end 43 | 44 | end 45 | 46 | 47 | structure TestAddCounting = 48 | struct 49 | 50 | structure IntOrder = 51 | struct 52 | type t = int 53 | val compare = Int.compare 54 | end 55 | 56 | structure TreeDictAddCounting = AddCounting(TreeDict(IntOrder)) 57 | 58 | (* Tests for AddCounting *) 59 | val testDict = TreeDictAddCounting.build([(0,1), (1,1), (2,5), (4,2)]) 60 | val SOME(1) = TreeDictAddCounting.lookup testDict 0 61 | val SOME(1) = TreeDictAddCounting.lookup testDict 1 62 | val SOME(1) = TreeDictAddCounting.lookup testDict 1 63 | val SOME(2) = TreeDictAddCounting.lookup testDict 4 64 | val SOME(2) = TreeDictAddCounting.lookup testDict 4 65 | val SOME(2) = TreeDictAddCounting.lookup testDict 4 66 | val 1 = TreeDictAddCounting.hits testDict 0 67 | val 2 = TreeDictAddCounting.hits testDict 1 68 | val 0 = TreeDictAddCounting.hits testDict 2 69 | val 3 = TreeDictAddCounting.hits testDict 4 70 | 71 | end 72 | 73 | -------------------------------------------------------------------------------- /hw/08/solutions/code/treefind.sml: -------------------------------------------------------------------------------- 1 | structure TreeFind = 2 | struct 3 | datatype 'a ntree = Empty 4 | | Node of 'a * ('a ntree list) 5 | 6 | exception NoSubtree 7 | (* find : ('a -> bool) -> 'a ntree -> 'a ntree *) 8 | (* REQUIRES : true *) 9 | (* ENSURES : find p T evaluates to a subtree of T such that p is true 10 | * for the root element of T *) 11 | fun find (p : 'a -> bool) (T : 'a ntree) : 'a ntree = 12 | case T of 13 | Empty => raise NoSubtree 14 | | Node(elem, L) => 15 | if (p elem) : bool 16 | then T 17 | else (case L of 18 | [] => raise NoSubtree 19 | | x::xs => 20 | ((find p x):'a ntree ) handle NoSubtree => 21 | find p (Node(elem, xs))) 22 | end 23 | 24 | structure TestTreeFind = 25 | struct 26 | 27 | open TreeFind 28 | 29 | val emp = Empty 30 | val single = Node(1,[]) 31 | val line = Node(3,[Node(2,[Node(5,[Node(9,[])])])]) 32 | val multi1 = Node(5,[Node(2,[]),Node(4,[])]) 33 | val multi2 = Node(5,[Node(3,[Node(11,[])]),Node(7,[]),Node(1,[Node(9,[]),Node(6,[])])]) 34 | 35 | val odd = (fn x => (x mod 2) = 1) 36 | val even = (fn x => (x mod 2) = 0) 37 | val eqTo = (fn target => fn test => Int.compare(target,test) = EQUAL) 38 | 39 | (* Testing Empty Tree *) 40 | fun testEmpty () : bool = 41 | let 42 | val Empty = find odd emp handle _ => Empty 43 | val Node(~1,[]) = find (eqTo 0) emp handle _ => Node(~1,[]) 44 | in 45 | true 46 | end 47 | 48 | (* Testing Single *) 49 | fun testSingle () : bool = 50 | let 51 | val Node(1,[]) = find odd single 52 | val Node(~1,[]) = find even single handle _ => Node(~1,[]) 53 | in 54 | true 55 | end 56 | 57 | (* Testing Line *) 58 | fun testLine () : bool = 59 | let 60 | val Empty = find (eqTo 11) line handle _ => Empty 61 | val Node(9,[]) = find (eqTo 9) line 62 | val Node(5,[Node(9,[])]) = find (eqTo 5) line 63 | val Node(3,[Node(2,[Node(5,[Node(9,[])])])]) = find (eqTo 3) line 64 | in 65 | true 66 | end 67 | 68 | (* Testing Multi *) 69 | fun testMulti () : bool = 70 | let 71 | val Node(4,[]) = find (eqTo 4) multi1 72 | val Node(5,[Node(2,[]),Node(4,[])]) = find odd multi1 73 | val Node(3,[Node(11,[])]) = find (eqTo 3) multi2 74 | val Node(6,[]) = find even multi2 75 | in 76 | true 77 | end 78 | 79 | val true = testEmpty() 80 | val true = testSingle() 81 | val true = testLine() 82 | val true = testMulti() 83 | 84 | end 85 | -------------------------------------------------------------------------------- /hw/09/code/util.sml: -------------------------------------------------------------------------------- 1 | structure Util : UTIL = 2 | struct 3 | (* first component is (char 0 , ... char (i - 1)) 4 | position i is included in the second component *) 5 | fun splitAt (s , i) = 6 | SOME (String.extract (s , 0, SOME i), String.extract (s , i , NONE)) 7 | handle Subscript => NONE 8 | 9 | fun peelOff (this : string, from : string) : string option = 10 | case splitAt (from , String.size this) of 11 | SOME (first , rest) => 12 | (case first = this of 13 | true => SOME rest 14 | | false => NONE) 15 | | NONE => NONE 16 | 17 | fun viewFirst (s : string) : (char * string) option = 18 | case String.size s of 19 | 0 => NONE 20 | | _ => SOME (String.sub (s,0) , String.extract (s , 1, NONE)) 21 | 22 | fun digit d = 23 | case d of 24 | #"0" => true 25 | | #"1" => true 26 | | #"2" => true 27 | | #"3" => true 28 | | #"4" => true 29 | | #"5" => true 30 | | #"6" => true 31 | | #"7" => true 32 | | #"8" => true 33 | | #"9" => true 34 | | _ => false 35 | 36 | fun peelInt (from : string) : (int * string) option = 37 | let 38 | fun peel (from : string) : (char list * string) option = 39 | case viewFirst from of 40 | NONE => NONE 41 | | SOME (first , s) => 42 | (case digit first of 43 | false => NONE 44 | | true => (case peel s of 45 | NONE => SOME ([first] , s) 46 | | SOME (cs , s) => SOME (first :: cs , s))) 47 | in 48 | case viewFirst from of 49 | NONE => NONE 50 | | SOME (c , s) => 51 | let 52 | val (neg,rest) = case c of #"~" => ("~",s) | _ => (" ",from) 53 | in 54 | case peel rest of 55 | SOME (cs , s) => 56 | (case Int.fromString (neg ^ String.implode cs) of 57 | SOME i => SOME (i, s) 58 | | NONE => NONE) 59 | | NONE => NONE 60 | end 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /lab/05/code/lab05.sml: -------------------------------------------------------------------------------- 1 | (***** Section 3 Higher Order Functions *****) 2 | 3 | (* Task 3.1 *) 4 | val double: int -> int = fn x => 2 * x 5 | val quadruple : int -> int = fn x => double(double(x)) 6 | 7 | (* Task 3.2 *) 8 | fun thenAddOne ((f:int -> int), (x:int)) : int = f(x) + 1 9 | 10 | (* Tests for thenAddOne *) 11 | val 5 = thenAddOne(double, 2) 12 | val 13 = thenAddOne(quadruple, 3) 13 | val ~1 = thenAddOne(fn x => ~x, 2) 14 | 15 | (* doubleList and quadrupleList reproduced for your convenience *) 16 | 17 | fun doubleList ([] : int list): int list = [] 18 | | doubleList (x::xs) = 19 | (double x)::(doubleList xs) 20 | 21 | fun quadrupleList ([]:int list): int list = [] 22 | | quadrupleList (x::xs) = 23 | (quadruple x)::(quadrupleList xs) 24 | 25 | (* Task 3.3 *) 26 | fun mapList (f: 'a -> 'b, [] : 'a list): 'b list = [] 27 | | mapList (f: 'a -> 'b, x::L : 'a list): 'b list = (f x)::mapList(f, L) 28 | 29 | (* Task 3.4 *) 30 | fun mapList' (f: 'a -> 'b) (L : 'a list) : 'b list = mapList(f, L) 31 | 32 | (* Task 3.5 *) 33 | (* Tests for mapList *) 34 | val [2,4,6] = mapList(double, [1,2,3]) 35 | val [4,12] = mapList(quadruple, [1,3]) 36 | val [~3,~4,~5] = mapList(fn x => ~x, [3,4,5]) 37 | 38 | (* Tests for mapList' *) 39 | val [2,4,6] = mapList'(double) ([1,2,3]) 40 | val [4,12] = mapList'(quadruple) ([1,3]) 41 | val [~3,~4,~5] = mapList'(fn x => ~x) ([3,4,5]) 42 | 43 | 44 | (***** Section 4 Options ******) 45 | (* Task 4.1 *) 46 | fun findOdd ([] : int list) : int option = NONE 47 | | findOdd (x::l : int list) : int option = 48 | if x mod 2 = 1 49 | then SOME x 50 | else findOdd l 51 | 52 | (* Tests for fimdOdd *) 53 | val SOME 3 = findOdd([2,3,4,5]) 54 | val NONE = findOdd([2,4]) 55 | val NONE = findOdd([]) 56 | 57 | (* subsetSumCert provided for your convenience *) 58 | fun subsetSumCert (nil : int list, s : int): bool * int list = (s=0, nil) 59 | | subsetSumCert (x::xs, s) = 60 | case subsetSumCert (xs, s-x) of 61 | (true, l1) => (true, x::l1) 62 | | (false, _) => subsetSumCert (xs,s) 63 | 64 | (* Task 4.2 *) 65 | fun subsetSumOption (l : int list, 0 : int) : int list option = SOME [] 66 | | subsetSumOption (nil : int list, s : int) : int list option = NONE 67 | | subsetSumOption (x::xs, s) = 68 | case subsetSumOption (xs, s-x) of 69 | SOME l1 => SOME (x::l1) 70 | | NONE => subsetSumOption (xs,s) 71 | 72 | (* Tests for subsetSumOption *) 73 | val SOME [1,2,4] = subsetSumOption([1,2,9,4], 7) 74 | val NONE = subsetSumOption([1,2,3], 8) 75 | -------------------------------------------------------------------------------- /src/sequence/sequence-sig.sml: -------------------------------------------------------------------------------- 1 | signature SEQUENCE = 2 | sig 3 | include SEQUENCECORE 4 | 5 | (* mapreduce l e n s == reduce n e (map l s) *) 6 | val mapreduce : ('a -> 'b) -> 'b -> ('b * 'b -> 'b) -> 'a seq -> 'b 7 | (* Intuitively toString computes the string representation of a sequence 8 | * in the same style as the string for a list, using the given function to 9 | * convert each element to a string. More precisely: 10 | * toString elmToStr == "[" ^ elmToStr x_0 ^ ", " ... ^ elmToStr x_(n-1) ^ "]". *) 11 | val toString : ('a -> string) -> 'a seq -> string 12 | 13 | (* repeat n x == such that all x_i == x *) 14 | val repeat : int -> 'a -> 'a seq 15 | (* zip (, ) == <(x_0, y_0), ..., (x_k, y_k)> where 16 | * k = min(n,m). That is, zip truncates the longer sequence if needed *) 17 | val zip : ('a seq * 'b seq) -> ('a * 'b) seq 18 | (* flatten ss == reduce append <> ss (the sequence analog of concat). 19 | * See below for the specification of append. *) 20 | val flatten : 'a seq seq -> 'a seq 21 | 22 | (* split k == (, ) 23 | (so the left result has length k) 24 | if the sequence has at least k elements 25 | 26 | or raises Range otherwise 27 | *) 28 | val split : int -> 'a seq -> 'a seq * 'a seq 29 | 30 | (* take k == 31 | drop k == 32 | if the sequence has at least k elements 33 | 34 | or raise Range otherwise 35 | *) 36 | val take : int -> 'a seq -> 'a seq 37 | val drop : int -> 'a seq -> 'a seq 38 | 39 | (* empty () == <> *) 40 | val empty : unit -> 'a seq 41 | (* cons x_0 == *) 42 | val cons : 'a -> 'a seq -> 'a seq 43 | 44 | (* singleton x == *) 45 | val singleton : 'a -> 'a seq 46 | (* append == *) 47 | val append : 'a seq -> 'a seq -> 'a seq 48 | 49 | 50 | (* DRL, Spring 2012: 51 | made some interface-level changes to currying/argument order. 52 | these still need to get pushed through the HWs and labs. 53 | 54 | what changed: 55 | toString: swapped argument order and curried 56 | repeat: curried 57 | nth/split/take/drop: integer first 58 | append : curried 59 | cons: curried 60 | *) 61 | end 62 | -------------------------------------------------------------------------------- /lab/07/code/lab07.sml: -------------------------------------------------------------------------------- 1 | exception Unimplemented 2 | 3 | 4 | (*********************** Task 3 ***********************) 5 | 6 | (* Datatype definition for polymorphic trees *) 7 | datatype 'a tree = Empty 8 | | Node of 'a tree * 'a * 'a tree 9 | 10 | (* Task 3.1 : DOCUMENT, IMPLEMENT, and TEST this function: *) 11 | (* 12 | * size : 'a tree -> (int -> 'b) -> 'b 13 | * REQUIRES: 14 | * ENSURES: 15 | *) 16 | fun size (Empty : 'a tree) (k : int -> 'b) : 'b = k(0) 17 | | size (Node(l,x,r) : 'a tree) (k : int -> 'b) : 'b = size l (fn y => size r (fn z => k(1 + z))) 18 | 19 | 20 | (* Datatype definition for regular expressions as defined in lecture *) 21 | datatype regexp = Zero 22 | | One 23 | | Char of char 24 | | Plus of regexp * regexp 25 | | Times of regexp * regexp 26 | | Star of regexp 27 | 28 | 29 | val validChars = String.explode "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSUVWXYZ.-" 30 | 31 | 32 | (* 33 | * anyChar : char list -> regexp 34 | * REQUIRES: 35 | * ENSURES: 36 | *) 37 | fun anyChar (L : char list) : regexp = foldr (fn (c,R) => Plus(Char c, R)) (Zero) L 38 | 39 | (* Test cases *) 40 | val Zero = anyChar [] 41 | val Plus(Char #"c", Zero) = anyChar [#"c"] 42 | val Plus(Char #"p", Plus(Char #"l", Zero)) = anyChar [#"p",#"l"] 43 | 44 | 45 | (* 46 | * fromString : string -> regexp 47 | * REQUIRES: 48 | * ENSURES: 49 | *) 50 | fun fromString s = foldr (fn (c,R) => Times(Char c, R)) (Zero) String.explode(s) 51 | 52 | 53 | 54 | (* 55 | * anyString : string list -> regexp 56 | * REQUIRES: 57 | * ENSURES: 58 | *) 59 | fun anyString (L : string list) : regexp = raise Unimplemented 60 | 61 | 62 | 63 | (* 64 | * emailer : string -> regexp 65 | * REQUIRES: 66 | * ENSURES: *) 67 | fun emailer (d : string) : regexp = raise Unimplemented 68 | 69 | (********************** Task 5 ********************) 70 | 71 | (* Type definition for polynomials as defined in handout *) 72 | type poly = int -> real 73 | 74 | (* Task 5.1 : DOCUMENT, IMPLEMENT, and TEST these functions: *) 75 | (* 76 | * add : poly * poly -> poly 77 | * REQUIRES: 78 | * ENSURES: *) 79 | fun add (p1 : poly, p2 : poly) : poly = fn x => p1(x) + p2(x) 80 | 81 | 82 | 83 | (* 84 | * mult : poly * poly -> poly 85 | * REQUIRES: 86 | * ENSURES: 87 | *) 88 | fun mult (p1 : poly, p2 : poly) : poly = fn x => p1(x) * p2(x) 89 | 90 | 91 | 92 | (* 93 | * eval : poly -> int -> real -> real 94 | * REQUIRES: 95 | * ENSURES: 96 | *) 97 | fun eval (p : poly) (0 : int) (x : real) : real = raise Unimplemented 98 | 99 | -------------------------------------------------------------------------------- /hw/10/code/rat.twobody.3day.auto.txt: -------------------------------------------------------------------------------- 1 | 2 | (0, 0),(0, ~149600000000) 3 | (0, ~7266212549208/546390625),(~25729920000, ~25382636804426368/174845) 4 | (~2439755118059437019711420923401562500000000000000000000000000/1590311346462619707618003924003145623664874530822174351549, ~30632408368437424942174439109895599561155746120154478926204587307046384/868931210538302321182718425288531239280265585442509607801827828125),(~81024846937374697931232521501940205165494656976184160582815292160000/1590311346462619707618003924003145623664874530822174351549, ~38333759381110443688669966393301756940197104636728480653091039498634488064/278057987372256742778469896092329996569684987341603074496584905) 5 | (~5736923909620454341422077588195129828748276072318849440029428099525649195163857259428552095652149166526968026598038931564282083310613831950792501255926030448562466760613167106622100185866526622772986780078125000000000000000000000000/1078155472062302837192451959383031401104576797137041629339507146945141470052346179995379789852050863219329646555263117456117001347698970378637134754135876612001708602242722873501054905939440734004306996055742991255731454587758801, ~37291509584236879088999658960069720107107250344963611458705183082785293459605684525956042047484379360986019917178459298831649301931677024725204528528366031296399121567752202936688165665158494779234101097133800601857221515479866292496942738824/589094042227291686152857071369769141644155406548206386505831647211322688535320212004038060489630728686199037662359311786296178439495082737040030706521522956954496064247277752554037328215567234803072052266769947831588644304364648627640625),(~81312443826916735221769125410210947679217845037811227045575767947155950829242265604103103368150893755621499149273491622665598123960789541650035261585519483161133406659071003924826503434199874999166816805672341866712009604080000787077760000/1078155472062302837192451959383031401104576797137041629339507146945141470052346179995379789852050863219329646555263117456117001347698970378637134754135876612001708602242722873501054905939440734004306996055742991255731454587758801, ~24227903655379801744001701659605854709285713000280020259491896722062816825103283737477586386435770354090130951908606328132097830920945800840267973345092640984020739866818911508269402017731266996818135308661410182286011123914185778696732645394304/188510093512733339568914262838326125326129730095426043681866127107623260331302467841292179356681833179583692051954979771614777100638426475852809826086887346225438740559128880817291945028981515136983056725366383306108366177396687560845) 6 | -------------------------------------------------------------------------------- /hw/10/code/tests/rat.twobody.3day.auto.txt: -------------------------------------------------------------------------------- 1 | 2 | (0, 0),(0, ~149600000000) 3 | (0, ~7266212549208/546390625),(~25729920000, ~25382636804426368/174845) 4 | (~2439755118059437019711420923401562500000000000000000000000000/1590311346462619707618003924003145623664874530822174351549, ~30632408368437424942174439109895599561155746120154478926204587307046384/868931210538302321182718425288531239280265585442509607801827828125),(~81024846937374697931232521501940205165494656976184160582815292160000/1590311346462619707618003924003145623664874530822174351549, ~38333759381110443688669966393301756940197104636728480653091039498634488064/278057987372256742778469896092329996569684987341603074496584905) 5 | (~5736923909620454341422077588195129828748276072318849440029428099525649195163857259428552095652149166526968026598038931564282083310613831950792501255926030448562466760613167106622100185866526622772986780078125000000000000000000000000/1078155472062302837192451959383031401104576797137041629339507146945141470052346179995379789852050863219329646555263117456117001347698970378637134754135876612001708602242722873501054905939440734004306996055742991255731454587758801, ~37291509584236879088999658960069720107107250344963611458705183082785293459605684525956042047484379360986019917178459298831649301931677024725204528528366031296399121567752202936688165665158494779234101097133800601857221515479866292496942738824/589094042227291686152857071369769141644155406548206386505831647211322688535320212004038060489630728686199037662359311786296178439495082737040030706521522956954496064247277752554037328215567234803072052266769947831588644304364648627640625),(~81312443826916735221769125410210947679217845037811227045575767947155950829242265604103103368150893755621499149273491622665598123960789541650035261585519483161133406659071003924826503434199874999166816805672341866712009604080000787077760000/1078155472062302837192451959383031401104576797137041629339507146945141470052346179995379789852050863219329646555263117456117001347698970378637134754135876612001708602242722873501054905939440734004306996055742991255731454587758801, ~24227903655379801744001701659605854709285713000280020259491896722062816825103283737477586386435770354090130951908606328132097830920945800840267973345092640984020739866818911508269402017731266996818135308661410182286011123914185778696732645394304/188510093512733339568914262838326125326129730095426043681866127107623260331302467841292179356681833179583692051954979771614777100638426475852809826086887346225438740559128880817291945028981515136983056725366383306108366177396687560845) 6 | -------------------------------------------------------------------------------- /src/sequence/vectorcore.sml: -------------------------------------------------------------------------------- 1 | structure VectorCore :> SEQUENCECORE = 2 | struct 3 | type 'a seq = 'a vector 4 | 5 | exception Range of string 6 | 7 | val length = Vector.length 8 | 9 | fun nth i s = 10 | case (Int.compare (i,0), Int.compare(i, (length s) - 1)) 11 | of (LESS,_) => raise (Range "nth called with a negative index") 12 | | (_,GREATER) => raise (Range "nth called with too large an index") 13 | | _ => Vector.sub (s,i) 14 | 15 | fun tabulate f n = 16 | case (Int.compare (n,0), Int.compare (n, Vector.maxLen)) 17 | of (LESS,_) => raise Range "tabulate called with a negative length argument" 18 | | (_, GREATER) => raise Range "tabulate called with too large a length argument" 19 | | _ => 20 | (* if the spec given in the Basis is correct, this tabulate 21 | * won't itself raise Size *) 22 | Vector.tabulate(n, f) 23 | handle Size => raise Range "tabulate applied to a function that raised Size" 24 | | Range s => raise (Range ("tabulate applied to a function that raised Range with" 25 | ^ "\"" ^ s ^ "\"")) 26 | 27 | fun filter f s = 28 | Vector.fromList 29 | (Vector.foldr (fn (e, xs) => case f e of true => e::xs | _ => xs) [] s) 30 | 31 | fun map f s = Vector.map f s 32 | handle (Range s) => 33 | raise Range ("map called with a function that raised Range with \"" 34 | ^ s ^ "\"") 35 | 36 | fun reduce f b s = Vector.foldr f b s 37 | handle (Range s) => 38 | raise Range ("reduce called with a function that raised Range with \"" 39 | ^ s ^ "\"") 40 | 41 | datatype 'a lview = Nil | Cons of 'a * 'a seq 42 | datatype 'a tview = Empty | Leaf of 'a | Node of 'a seq * 'a seq 43 | 44 | fun showl s = 45 | case length s 46 | of 0 => Nil 47 | | l => Cons(nth 0 s, tabulate (fn i => nth (i+1) s) (l-1)) 48 | 49 | fun hidel Nil = Vector.fromList [] 50 | | hidel (Cons (x,xs)) = Vector.concat [Vector.fromList [x], xs] 51 | 52 | fun showt s = 53 | case length s 54 | of 0 => Empty 55 | | 1 => Leaf (nth 0 s) 56 | | n => 57 | let 58 | val mid = n div 2 59 | in 60 | Node (tabulate (fn i => nth i s) mid, 61 | tabulate (fn x => nth (x + mid) s) (n - mid)) 62 | end 63 | 64 | fun hidet Empty = Vector.fromList [] 65 | | hidet (Leaf x) = Vector.fromList [x] 66 | | hidet (Node(s1,s2)) = Vector.concat [s1,s2] 67 | end 68 | -------------------------------------------------------------------------------- /hw/02/solutions/code/hw02-sol.sml: -------------------------------------------------------------------------------- 1 | (* evenP : int -> bool 2 | * REQUIRES: true 3 | * ENSURES: evenP n returns true if n is even and false otherwise 4 | *) 5 | fun evenP (n : int) : bool = (n mod 2 = 0) 6 | 7 | (* oddP : int -> bool 8 | * REQUIRES: true 9 | * ENSURES: oddP n returns true if n is odd and false otherwise 10 | *) 11 | fun oddP (n : int) : bool = (n mod 2 = 1) 12 | 13 | (* add : int * int -> int 14 | * REQUIRES: n, m >= 0 15 | * ENSURES: add(n,m) = n+m 16 | *) 17 | fun add (0 : int, m : int) : int = m 18 | | add (n : int, m : int) : int = 1 + add(n-1, m) 19 | 20 | val 7 = add(0,7) 21 | val 17 = add(10,7) 22 | 23 | 24 | (* leq : int * int -> bool 25 | * REQUIRES: x, y >= 0 26 | * ENSURES: leq (x,y) returns true if x <= y and false otherwise 27 | *) 28 | fun leq (0 : int, y : int) : bool = true 29 | | leq (x : int, 0 : int) : bool = false 30 | | leq (x : int, y : int) : bool = leq(x-1, y-1) 31 | 32 | val true = leq(0,7) 33 | val false = leq(9,7) 34 | 35 | 36 | (* halfSum : int -> real 37 | * REQUIRES: n >= 0 38 | * ENSURES: halfSum(n) returns the nth number in the halfSum series. 39 | *) 40 | fun halfSum (0 : int) : real = 0.0 41 | | halfSum (n : int) : real = 0.5 + 0.5 * halfSum(n-1) 42 | 43 | val true = Real.==(halfSum 0, 0.0) 44 | val true = Real.==(halfSum 1, 0.5) 45 | val true = Real.==(halfSum 2, 0.75) 46 | val true = Real.==(halfSum 4, (1.0/2.0) + (1.0/4.0) + (1.0/8.0) + (1.0/16.0)) 47 | 48 | 49 | (* altHalfSum : int -> real 50 | * REQUIRES: n >= 0 51 | * ENSURES: altHalfSum(n) returns the nth number in the altHalfSum series. 52 | *) 53 | fun altHalfSum (0 : int) : real = 0.0 54 | | altHalfSum (n : int) : real = 0.5 - 0.5 * altHalfSum(n-1) 55 | 56 | val true = Real.==(altHalfSum 0, 0.0) 57 | val true = Real.==(altHalfSum 1, 0.5) 58 | val true = Real.==(altHalfSum 2, 0.25) 59 | val true = Real.==(altHalfSum 4, (1.0/2.0) - (1.0/4.0) + (1.0/8.0) - (1.0/16.0)) 60 | 61 | (* is_prime_helper : int * int -> bool 62 | * REQUIRES: n > 1, k > 0 63 | * ENSURES: is_prime_helper(n, k) returns true if n is prime and false otherwise 64 | *) 65 | fun is_prime_helper (n : int, k : int) : bool = 66 | case (k, n mod k) of 67 | (1, _) => true 68 | | (_, 0) => false 69 | | _ => is_prime_helper (n, k - 1) 70 | val true = is_prime_helper(2, 1) 71 | val true = is_prime_helper(5, 4) 72 | val false = is_prime_helper(78, 77) 73 | 74 | (* is_prime : int -> bool 75 | * REQUIRES: n > 1 76 | * ENSURES: is_prime(n) returns true if n is prime and false otherwise 77 | *) 78 | fun is_prime (n : int) : bool = is_prime_helper(n, n-1) 79 | val true = is_prime 2 80 | val true = is_prime 19 81 | val false = is_prime 65 82 | -------------------------------------------------------------------------------- /hw/11/code/minimax.sml: -------------------------------------------------------------------------------- 1 | functor MiniMax (Settings : sig 2 | structure G : GAME 3 | val search_depth : int 4 | end 5 | ) : PLAYER = 6 | struct 7 | structure Game = Settings.G 8 | 9 | type edge = (Game.move * Game.est) 10 | fun valueOf ((_,value) : edge) = value 11 | fun moveOf ((move,_) : edge) = move 12 | 13 | fun max ((m1,v1) : edge, (m2,v2) : edge) : edge = 14 | case Game.Est.compare (v1, v2) of 15 | LESS => (m2, v2) 16 | | _ => (m1, v1) 17 | 18 | fun min ((m1,v1) : edge, (m2,v2) : edge) : edge = 19 | case Game.Est.compare (v1, v2) of 20 | GREATER => (m2, v2) 21 | | _ => (m1, v1) 22 | 23 | fun vmax (v1, v2) : Game.est = 24 | case Game.Est.compare (v1, v2) of 25 | LESS => v2 26 | | _ => v1 27 | 28 | fun vmin (v1, v2) : Game.est = 29 | case Game.Est.compare (v1, v2) of 30 | GREATER => v2 31 | | _ => v1 32 | 33 | fun score (s : Game.state) : Game.est = 34 | case Game.status s of 35 | Game.Over (Game.Draw) => Game.Est.draw 36 | | Game.Over (Game.Winner (Game.Minnie)) => Game.Est.minnie_wins 37 | | Game.Over (Game.Winner (Game.Maxie)) => Game.Est.maxie_wins 38 | | Game.In_play => raise Fail "No moves available" 39 | 40 | fun F (d : int) (s : Game.state) : Game.est = 41 | let 42 | val moves = Game.moves s 43 | in 44 | if SeqUtils.null moves then score s else 45 | if d = 0 then Game.estimate s else 46 | SeqUtils.reduce1 vmax 47 | (Seq.map (fn mv => G (d - 1) (Game.make_move (s, mv))) (moves)) 48 | end 49 | 50 | and G (d : int) (s : Game.state) : Game.est = 51 | let 52 | val moves = Game.moves s 53 | in 54 | if SeqUtils.null moves then score s else 55 | if d = 0 then Game.estimate s else 56 | SeqUtils.reduce1 vmin 57 | (Seq.map (fn mv => F (d - 1) (Game.make_move (s, mv))) (moves)) 58 | end 59 | 60 | fun next_move (s : Game.state) : Game.move = 61 | let 62 | val moves = Game.moves s 63 | in 64 | case Game.player s of 65 | Game.Minnie => 66 | moveOf (SeqUtils.reduce1 min 67 | (Seq.map (fn mv => (mv, F (Settings.search_depth - 1) 68 | (Game.make_move (s, mv)))) moves)) 69 | | Game.Maxie => 70 | moveOf (SeqUtils.reduce1 max 71 | (Seq.map (fn mv => (mv, G (Settings.search_depth - 1) 72 | (Game.make_move (s, mv)))) moves)) 73 | end 74 | end 75 | -------------------------------------------------------------------------------- /hw/08/solutions/code/fundict.sml: -------------------------------------------------------------------------------- 1 | (********** TASK 4.1 **********) 2 | functor FunDict (K : ORDERED) : DICT = 3 | struct 4 | structure Key = K 5 | 6 | datatype 'v func = Func of (Key.t -> 'v option) 7 | 8 | type 'v dict = 'v func 9 | 10 | (* ENSURES : empty is a dictionary that contains no mappings *) 11 | val empty = Func (fn _ => NONE) 12 | 13 | (* insert : 'v dict -> Key.t * 'v -> 'v dict *) 14 | (* REQUIRES : true *) 15 | (* ENSURES : insert f (k,v) inserts v into f at key k *) 16 | fun insert (Func f) (k, v) = 17 | Func 18 | (fn k' => 19 | case Key.compare (k, k') of 20 | EQUAL => SOME v 21 | | _ => f k') 22 | 23 | (* lookup : 'v dict -> Key.t -> 'v option *) 24 | (* REQUIRES: true *) 25 | (* ENSURES: lookup f k finds the value of k in dictionary f*) 26 | fun lookup (Func f) k = f k 27 | 28 | (* remove : 'v dict -> Key.t -> 'v dict *) 29 | (* REQUIRES: true *) 30 | (* ENSURES: remove f k removes k and its value from f*) 31 | fun remove (Func f) k = 32 | Func 33 | (fn k' => 34 | case Key.compare (k,k') of 35 | EQUAL => NONE 36 | | _ => f k') 37 | 38 | (* map : ('v -> ''v) -> 'v dict -> ''v dict *) 39 | (* REQUIRES : g is total *) 40 | (* ENSURES: map g d maps a function g over all values in d *) 41 | fun map g d = 42 | Func 43 | (fn k' => 44 | case (lookup d k') of 45 | SOME x => SOME (g x) 46 | | _ => NONE) 47 | 48 | (* filter : ('v -> bool) -> 'v dict -> 'v dict *) 49 | (* REQUIRES: p is total *) 50 | (* ENSURES: filter p d returns a dictionary of all values in d satisfying 51 | * the predicate p. *) 52 | fun filter p d = 53 | Func 54 | (fn k' => 55 | case (lookup d k') of 56 | SOME x => 57 | (case (p x) of 58 | true => SOME x 59 | | false => NONE) 60 | | _ => NONE) 61 | end 62 | 63 | structure TestFunDict = 64 | struct 65 | 66 | structure IntDict = FunDict(IntOrder) 67 | open IntDict 68 | 69 | fun testFD () : bool = 70 | let 71 | val emp : int dict = empty 72 | val ins1 = insert empty (1,1) 73 | val ins2 = insert ins1 (2,2) 74 | 75 | val NONE = lookup emp 1 76 | val SOME(1) = lookup ins1 1 77 | val SOME(2) = lookup ins2 2 78 | val NONE = lookup ins2 3 79 | 80 | val testRem = remove ins2 1 81 | val NONE = lookup testRem 1 82 | val SOME(2) = lookup testRem 2 83 | 84 | val mapped = map (fn v => v+5) ins2 85 | val SOME(6) = lookup mapped 1 86 | val SOME(7) = lookup mapped 2 87 | 88 | val filtered = filter (fn v => (v mod 2) = 0) mapped 89 | val NONE = lookup filtered 2 90 | val SOME(6) = lookup filtered 1 91 | in 92 | true 93 | end 94 | 95 | val true = testFD() 96 | 97 | end 98 | -------------------------------------------------------------------------------- /hw/12/code/memo.sml: -------------------------------------------------------------------------------- 1 | (* Task 4.1 *) 2 | functor MemoedFibo (D : DICT where type Key.t = IntInf.int) : FIBO = 3 | struct 4 | 5 | val fibDict : IntInf.int D.dict ref = ref D.empty; 6 | val _ = fibDict := D.insert (!fibDict) (0,0) 7 | val _ = fibDict := D.insert (!fibDict) (1,1) 8 | 9 | (* fib : IntInf.int -> IntInf.int *) 10 | (* REQUIRES: n>=0 *) 11 | (* ENSURES: fib n evaluates to the nth Fibonacci number *) 12 | fun fib (n : IntInf.int) : IntInf.int = 13 | case (D.lookup (!fibDict) n) of 14 | SOME(x) => x 15 | | _ => let 16 | val x = fib(n-2) + fib(n-1) 17 | val _ = fibDict := D.insert (!fibDict) (n,x) 18 | in 19 | x 20 | end 21 | 22 | end 23 | 24 | (* Task 4.2 *) 25 | (* If the result is not memoized, this code calls f to get the result to 26 | * memoize. However it does not call the memoized version of f. This makes 27 | * the code much slower because any recursive calls in f will not check to see 28 | * if their result is memoized. *) 29 | 30 | (* Task 4.3 *) 31 | functor Memoizer (D : DICT) : MEMOIZER = 32 | struct 33 | structure D = D 34 | 35 | (* memo : ((D.Key.t -> 'a) -> (D.Key.t -> 'a)) -> (D.Key.t -> 'a) *) 36 | (* REQUIRES: true *) 37 | (* ENSURES: memo m evalutes to a memoized version of m *) 38 | fun memo (m : (D.Key.t -> 'a) -> (D.Key.t -> 'a)) : D.Key.t -> 'a = 39 | let 40 | val hist : 'a D.dict ref = ref D.empty 41 | 42 | fun m_memoed x = 43 | case D.lookup (!hist) x of 44 | SOME(b) => b 45 | | NONE => 46 | let 47 | val res = m m_memoed x 48 | val _ = (hist := D.insert (!hist) (x,res)) 49 | in 50 | res 51 | end 52 | in 53 | m_memoed 54 | end 55 | 56 | end 57 | 58 | (* Task 4.4 *) 59 | structure AutoMemoedFibo : FIBO = 60 | struct 61 | 62 | structure TreeIntInfMemoizer = Memoizer(TreeDict(IntInfLt)) 63 | 64 | (* fibHelper : (IntInf.int -> IntInf.int) -> IntInf.int -> IntInf.int *) 65 | (* REQUIRES: n>=0 *) 66 | (* ENSURES: fibHelper n evaluates to the nth Fibonacci number *) 67 | fun fibHelper (m : IntInf.int -> IntInf.int) (n : IntInf.int) : IntInf.int = 68 | case n of 69 | 0 => 0 70 | | 1 => 1 71 | | _ => m(n-2) + m(n-1) 72 | 73 | val fib = TreeIntInfMemoizer.memo fibHelper 74 | 75 | end 76 | 77 | 78 | structure TestAutoMemoedFibo = 79 | struct 80 | open AutoMemoedFibo 81 | 82 | (* Tests for AutoMemoedFibo *) 83 | val 0 = fib 0 84 | val 1 = fib 1 85 | val 5 = fib 5 86 | val 6765 = fib 20 87 | val 12586269025 = fib 50 88 | val 280571172992510140037611932413038677189525 = fib 200 89 | 90 | end 91 | -------------------------------------------------------------------------------- /lab/13/code/lab13.sml: -------------------------------------------------------------------------------- 1 | (* Lazy programming with nats and lists *) 2 | structure LazyProgrammer = 3 | struct 4 | 5 | datatype 'a lazylist = Nil 6 | | Cons of 'a * (unit -> 'a lazylist) 7 | 8 | datatype lazynat = Zero | Succ of unit -> lazynat 9 | 10 | (* Examples from the handout - feel free to reuse in your tests. *) 11 | (* Returns an infinite list of 0's *) 12 | fun zeros () = Cons (0, zeros) 13 | 14 | (* decreasing : int -> int lazylist 15 | REQUIRES: n >= 0 16 | ENSURES: decreasing n is a finite lazy list, 17 | consisting of the integers n, ..., 1, if n > 0; 18 | and NIL, if n=0. 19 | If n < 0, the function will still return a lazy list, now infinite, 20 | of the form n, n-1, n-2, ... 21 | *) 22 | fun decreasing 0 = Nil 23 | | decreasing n = Cons(n, fn () => decreasing(n-1)) 24 | 25 | (* take : 'a lazylist * int -> 'a list 26 | ENSURES: take(L, n) returns the first n elements of L, now as a regular 27 | list, unless L has fewer than n elements, in which case take raises Fail. 28 | *) 29 | fun take (L : 'a lazylist, 0 : int) : 'a list = nil 30 | | take (Nil, _) = raise Fail "tried to take from a Nil lazylist" 31 | | take (Cons(x, f), n) = x::take(f(),n-1) 32 | 33 | 34 | (* DOCUMENTATION GOES HERE *) 35 | fun lazy_append (L1 : 'a lazylist, L2 : 'a lazylist) : 'a lazylist = 36 | case (L1,L2) of 37 | (Cons(a, f), L4) => Cons(a, fn () => lazy_append(f(), L4)) 38 | | (Nil, L4) => L4 39 | 40 | 41 | (* returns the lazy representation of infinity *) 42 | fun infinity () = Succ infinity 43 | 44 | (* This means 2 + infinity, which is still infinity *) 45 | val silly_infinity = Succ (fn () => Succ infinity) 46 | 47 | (* Lazy representation of 2 *) 48 | val two = Succ (fn () => Succ (fn () => Zero)) 49 | 50 | (* DOCUMENTATION GOES HERE *) 51 | fun lazy_length (L : 'a lazylist) : lazynat = 52 | case L of 53 | Cons(a, f) => Succ(fn() => lazy_length(f())) 54 | | Nil => Zero 55 | 56 | (* Testing lazy_length is a little tricky unless you write lazy_cmp 57 | * below. Here's some testing code to get you started: *) 58 | fun minus1 (n : lazynat) : lazynat = 59 | case n of 60 | Zero => raise Fail "Tried to created negative nat" 61 | | Succ f => f () 62 | 63 | (* 64 | val two_list = Cons (4, fn () => Cons (5, fn () => Nil)) 65 | val Zero = minus1 (minus1 (lazy_length two_list)) 66 | *) 67 | 68 | 69 | (* BONUS *) 70 | (* DOCUMENTATION GOES HERE *) 71 | fun lazy_cmp (n : lazynat) (m : int) : order = 72 | case (n,m) of 73 | (Zero, 0) => EQUAL 74 | | (Zero, _) => LESS 75 | | (_, 0) => GREATER 76 | | (Succ(f), m) => (lazy_cmp (f()) (m-1)) 77 | 78 | 79 | (* DOCUMENTATION GOES HERE *) 80 | fun int_to_lazy (0 : int) : lazynat = Zero 81 | | int_to_lazy (n : int) : lazynat = Succ(fn() => int_to_lazy(n-1)) 82 | end 83 | -------------------------------------------------------------------------------- /hw/10/code/lib/ratplaneargs.sml: -------------------------------------------------------------------------------- 1 | functor RatPlaneArgs (S : SEQUENCE) :> PLANEARGS where Seq = S= 2 | struct 3 | structure Seq = S 4 | 5 | structure ScalarCore : SCALARCORE = 6 | struct 7 | open IntInf 8 | 9 | datatype rat = Frac of int * int 10 | type scalar = rat 11 | 12 | fun gcd (m, 0) = m 13 | | gcd (0, n) = n 14 | | gcd (m, n) = gcd (if m > n then (m mod n, n) else (m, n mod m)) 15 | 16 | fun lcm (m : int, n : int) : int = 17 | let 18 | val g = gcd (m, n) 19 | in 20 | m * n div g 21 | end 22 | 23 | fun fromRatio (n : int, d : int) : scalar = 24 | let 25 | val g = 26 | case (IntInf.compare (n, 0), IntInf.compare (d, 0)) of 27 | (_, EQUAL) => raise Fail "denominator can't be zero" 28 | | (EQUAL, _) => d 29 | | (LESS, GREATER) => gcd (~n, d) 30 | | (GREATER, LESS) => ~(gcd (n, ~d)) 31 | | (LESS, LESS) => ~(gcd (~n, ~d)) 32 | | (GREATER, GREATER) => gcd (n, d) 33 | in 34 | Frac (n div g, d div g) 35 | end 36 | 37 | fun plus (Frac (n1, d1) : scalar, Frac (n2, d2) : scalar) : scalar = 38 | let 39 | val cdenom = lcm (d1, d2) 40 | in 41 | Frac (n1 * cdenom div d1 + n2 * cdenom div d2, cdenom) 42 | end 43 | 44 | fun times (Frac (n1, d1) : scalar, Frac (n2, d2) : scalar) : scalar = 45 | fromRatio (n1 * n2, d1 * d2) 46 | 47 | fun minus (r1 : scalar, r2 : scalar) : scalar = 48 | plus (r1, times(fromRatio(~1,1),r2)) 49 | 50 | fun divide (r1 : scalar, r2 : scalar) : scalar = 51 | let 52 | fun inverse (Frac (n, d) : scalar) : scalar = 53 | case IntInf.compare (n, 0) of 54 | LESS => Frac (~d, ~n) 55 | | GREATER => Frac (d, n) 56 | | EQUAL => raise Div 57 | in 58 | times (r1, inverse r2) 59 | end 60 | 61 | fun compare (Frac (n1, d1) : scalar, Frac (n2, d2) : scalar) : order = 62 | let 63 | val cdenom = lcm (d1, d2) 64 | in 65 | IntInf.compare (n1 * cdenom div d1, n2 * cdenom div d2) 66 | end 67 | 68 | fun toString (Frac (n, 1)) = IntInf.toString n 69 | | toString (Frac (n, d)) = IntInf.toString n ^ "/" ^ IntInf.toString d 70 | end 71 | 72 | structure Scalar : SCALAR = MakeScalar(ScalarCore) 73 | 74 | (* Computes the distance between the argument points *) 75 | fun distance (x1,y1) (x2,y2) = 76 | let 77 | fun abs x = 78 | case Scalar.compare (x, Scalar.fromRatio(0,1)) 79 | of LESS => Scalar.negate x 80 | | _ => x 81 | 82 | val dx = Scalar.minus (x2,x1) 83 | val dy = Scalar.minus (y2,y1) 84 | in 85 | Scalar.plus (abs dx, abs dy) 86 | end 87 | end 88 | -------------------------------------------------------------------------------- /hw/08/code/stack.sml: -------------------------------------------------------------------------------- 1 | (* Task 4.1 *) 2 | functor Stack(T : TYPEDEF) : STACK = 3 | struct 4 | exception StackUnderflow 5 | 6 | type stacktype = T.t 7 | type stack = T.t list 8 | 9 | (* empty : unit -> stack *) 10 | (* REQUIRES: true *) 11 | (* ENSURES: empty evaluates to an empty stack *) 12 | val empty = fn () => [] 13 | 14 | (* push : (stack * stacktype) -> stack *) 15 | (* REQUIRES: true *) 16 | (* ENSURES: push(S,x) evaluates to S with x pushed onto the top *) 17 | fun push (S : stack, x : stacktype) : stack = x::S 18 | 19 | (* *) 20 | (* REQUIRES: true *) 21 | (* ENSURES: pop S evalutes to S with the top element removed 22 | * and raises StackUnderFlow if S is empty *) 23 | fun pop ([] : stack) : stacktype * stack = raise StackUnderflow 24 | | pop (x::S : stack) : stacktype * stack = (x, S) 25 | 26 | (* append : (stack * stack) -> stack *) 27 | (* REQUIRES: true *) 28 | (* ENSURES: append(S1,S2) evaluates to S1 put on top of S2 *) 29 | fun append(S1 : stack, S2 : stack) = S1 @ S2 30 | 31 | (* find : (stack * (stacktype -> bool)) -> stack option *) 32 | (* REQUIRES: true *) 33 | (* ENSURES: find(S,p) evaluates to the largest substack of S 34 | * whose top element satisfies p *) 35 | fun find ([] : stack, p : stacktype -> bool) : stack option = NONE 36 | | find (x::S : stack, p : stacktype -> bool) : stack option = 37 | if p x 38 | then SOME (x::S) 39 | else find(S, p) 40 | 41 | (* flip : stack -> stack *) 42 | (* REQUIRES: true *) 43 | (* ENSURES: flip S flips the stack S *) 44 | fun flip ([] : stack) : stack = [] 45 | | flip (x::S : stack) : stack = flip(S) @ [x] 46 | 47 | end 48 | 49 | 50 | structure TestStack = 51 | struct 52 | 53 | structure IntType : TYPEDEF = 54 | struct 55 | type t = int 56 | end 57 | 58 | structure IntStack : STACK = Stack(IntType) 59 | 60 | (* Tests for empty *) 61 | val [] = IntStack.empty() 62 | 63 | (* Tests for push *) 64 | val [3,1,2] = IntStack.push([1,2], 3) 65 | val [2,2,2] = IntStack.push([2,2], 2) 66 | val [4] = IntStack.push([], 4) 67 | 68 | (* Tests for pop *) 69 | val (1, [2,3]) = IntStack.pop([1,2,3]) 70 | val (2, [2,2]) = IntStack.pop([2,2,2]) 71 | val (4, []) = IntStack.pop([4]) 72 | 73 | (* Tests for flip *) 74 | val [3,2,1] = IntStack.flip([1,2,3]) 75 | val [2,2,2] = IntStack.flip([2,2,2]) 76 | val [4] = IntStack.flip([4]) 77 | 78 | (* Tests for append *) 79 | val [1,2,3,4,5,6] = IntStack.append([1,2,3], [4,5,6]) 80 | val [1,2,3,2,3,4] = IntStack.append([1,2,3], [2,3,4]) 81 | val [1,2,3] = IntStack.append([1,2,3], []) 82 | val [4,5,6] = IntStack.append([], [4,5,6]) 83 | val [] = IntStack.append([], []) 84 | 85 | (* Tests for find *) 86 | val SOME [1,2,3] = IntStack.find([1,2,3], fn x => x = 1) 87 | val SOME [2,3] = IntStack.find([1,2,3], fn x => x = 2) 88 | val SOME [2,2,2] = IntStack.find([2,2,2], fn x => x = 2) 89 | val NONE = IntStack.find([1,2,3], fn x => x = 4) 90 | val NONE = IntStack.find([], fn x => x = 1) 91 | 92 | end 93 | -------------------------------------------------------------------------------- /hw/07/code/hw07.sml: -------------------------------------------------------------------------------- 1 | 2 | (* Remove this when you're done to make sure you didn't miss anything *) 3 | exception Unimplemented 4 | 5 | datatype regexp = 6 | Zero 7 | | One 8 | | Char of char 9 | | Plus of regexp * regexp 10 | | Times of regexp * regexp 11 | | Star of regexp 12 | | Whatever 13 | | Both of regexp * regexp 14 | 15 | (* match : regexp -> char list -> (char list -> bool) -> bool *) 16 | (* REQUIRES; p is a total function *) 17 | (* ENSURES: match R L p evaluates to true if there exists L1, L2 such that L=L1@L2 and L1 is in R and p(L2)=true and false otherwise *) 18 | fun match (R : regexp) (L : char list) (p : char list -> bool) : bool = 19 | case R of 20 | Zero => false 21 | | One => p L 22 | | Char c => (case L of 23 | [] => false 24 | | c' :: L' => (c = c') andalso p L') 25 | | Plus (R1, R2) => match R1 L p orelse match R2 L p 26 | | Times (R1, R2) => match R1 L (fn L' => match R2 L' p) 27 | | Star R => p L orelse match R L (fn L' => (L <> L') andalso 28 | match (Star R) L' p) 29 | (* Task 2.1 *) 30 | | Whatever => (case L of 31 | [] => p L 32 | | c'::L' => p L orelse match R L' p) 33 | 34 | (* Task 2.2 *) 35 | | Both (R1, R2) => match R1 L (fn L' => match R2 L (fn L'' => p L' andalso L' = L'')) 36 | 37 | fun accept R s = match R (String.explode s) (fn [] => true | _ => false) 38 | 39 | (* Task 2.1 Tests *) 40 | val true = accept Whatever "abc" 41 | val true = accept Whatever "Hello World" 42 | val true = accept Whatever "" 43 | val false = match Whatever (String.explode("abc")) (fn x => x = [#"d"]) 44 | 45 | (* Task 2.2 Tests *) 46 | val R1 = Plus(Char #"a", Plus(Char #"b", Plus(Char #"c", Char #"d"))) 47 | val R2 = Plus(Char #"a", Plus(Char #"b", Plus(Char #"x", Char #"y"))) 48 | val true = accept (Both(R1,R2)) "a" 49 | val true = accept (Both(R1,R2)) "b" 50 | val false = accept (Both(R1,R2)) "c" 51 | val false = accept (Both(R1,R2)) "y" 52 | val false = accept (Both(R1,R2)) "" 53 | 54 | (* Task 3.1 *) 55 | (* halfmatch : regexp -> regexp -> char list -> bool *) 56 | (* REQUIRES: true *) 57 | (* ENSURES: halfmatch R1 R2 L evaluates to true if and only if there exists L1, L2 such that L=L1@L2, length(L1)=length(L2), and L1 is in R1 and L2 is in R2 *) 58 | fun halfmatch (R1 : regexp) (R2 : regexp) (L : char list) : bool = match R1 L (fn L' => match R2 L' (fn L'' => L'' = []) andalso length(L) = 2 * length(L')) 59 | 60 | (* Tests for halfmatch *) 61 | val R1 = Star(Plus(Char #"a", Plus(Char #"b", Char #"c"))) 62 | val R2 = Star(Plus(Char #"x", Plus(Char #"y", Char #"z"))) 63 | val true = halfmatch R1 R2 (String.explode("abcxyz")) 64 | val true = halfmatch R1 R2 (String.explode("abxz")) 65 | val false = halfmatch R1 R2 (String.explode("axy")) 66 | val false = halfmatch R1 R2 (String.explode("abc")) 67 | val false = halfmatch R1 R2 (String.explode("adxy")) 68 | val true = halfmatch R1 R2 (String.explode("")) 69 | -------------------------------------------------------------------------------- /hw/10/code/lib/mechanics.sml: -------------------------------------------------------------------------------- 1 | functor Mechanics (Plane : SPACE) : MECHANICS = 2 | struct 3 | 4 | structure Plane = Plane 5 | 6 | val ++ = Plane.++ 7 | val ** = Plane.** 8 | val --> = Plane.--> 9 | 10 | infixr 3 ++ 11 | infixr 4 ** 12 | infixr 3 --> 13 | 14 | (* ---------------------------------------------------------------------- *) 15 | (* n body *) 16 | (* throughout, we use SI units: 17 | mass is kg, length is meters, time is seconds, so force is Newtons *) 18 | 19 | (* (mass, position at time t, velocity at time t - (dt/2)), 20 | * where "dt" is the time step for the simulation. 21 | * 22 | * The position & velocity are out-of-sync because we are using "leapfrog 23 | * integration" to calculate the positions & velocities. However, you (the 24 | * student) should not need to worry about this, as it does not affect code 25 | * you will have to write. 26 | *) 27 | type body = Plane.Scalar.scalar * Plane.point * Plane.vec 28 | 29 | (* Projects the position field from a body *) 30 | fun position ((_,p,_) : body) = p 31 | 32 | fun bodyToString (_,p,v) = "P: " ^ (Plane.pointToString p) ^ "\t " ^ 33 | "V: " ^ (Plane.vecToString v) 34 | 35 | (* Gravitational constant G = 6.67428E~11 N (m/kg)^2 *) 36 | val G = Plane.Scalar.divide (Plane.Scalar.fromRatio (667428, 100000), 37 | Plane.Scalar.fromRatio (100000000000,1)) 38 | 39 | (* acceleration on a body at p1 due to a body of mass m2 at p2; 40 | 41 | math: 42 | magnitude: 43 | a1 = F / m1 44 | F = G m1 m2 / r^2 where r is the distance between them 45 | so a1 = G m2 / r^2, cancelling m1 46 | direction: the direction from body 1 to body 2 47 | *) 48 | fun accOnPoint (p1 : Plane.point, 49 | (m2, p2) : Plane.scalar * Plane.point) : Plane.vec = 50 | case Plane.pointEqual(p1 , p2) of 51 | true => Plane.zero 52 | | false => 53 | let 54 | val disp12 : Plane.vec = (p1 --> p2) 55 | val r = Plane.mag disp12 56 | val aMag = Plane.Scalar.divide (Plane.Scalar.times (G, m2), 57 | Plane.Scalar.times (r, r)) 58 | val aDir = Plane.unitVec disp12 59 | in 60 | aDir ** aMag 61 | end 62 | 63 | (* acceleration on body 1 due to body 2; 64 | * note: this is independent of the velocity of the bodies and also 65 | * independent ofthe mass of body 1. 66 | *) 67 | fun accOn ((_, p1, _) : body , (m2, p2, _) : body) : Plane.vec = 68 | accOnPoint (p1, (m2, p2)) 69 | 70 | (* stepBody (b, a, t) computes the new position and velocity of b 71 | * after a t seconds given that a is the acceleration. 72 | * We use leapfrog integration. 73 | *) 74 | fun stepBody ((m, p, v) : body, a : Plane.vec, t : Plane.scalar) : body = 75 | let 76 | val v_new = v ++ a ** t 77 | in 78 | (m, 79 | Plane.displace (p, v_new ** t), (* leapfrog *) 80 | v_new) 81 | end 82 | 83 | end 84 | -------------------------------------------------------------------------------- /hw/08/solutions/code/stack.sml: -------------------------------------------------------------------------------- 1 | functor Stack (T : TYPEDEF) : STACK = 2 | struct 3 | type stacktype = T.t 4 | type stack = stacktype list 5 | 6 | exception StackUnderflow 7 | (* empty : unit -> stack *) 8 | (* REQUIRES: true *) 9 | (* ENSURES: empty() returns an empty stack *) 10 | fun empty () : stack = [] 11 | 12 | (* push : stack * stacktype -> stack *) 13 | (* REQUIRES: true *) 14 | (* ENSURES: push(S,elem) returns a stack with elem 15 | * pushed onto S *) 16 | fun push (S : stack, elem : stacktype) = elem::S 17 | 18 | (* pop : stack -> stacktype * stack *) 19 | (* REQUIRES: pop is not empty *) 20 | (* ENSURES: pop L returns a tuple containing the first 21 | * element e popped off of L and the remaining 22 | * stack after popping e off of L; if L is 23 | * empty, pop L raises a StackUnderflow exception *) 24 | fun pop (L : stack) : stacktype * stack = case L of 25 | [] => raise StackUnderflow 26 | | x::xs => (x, xs) 27 | 28 | (* append : stack * stack -> stack *) 29 | (* REQUIRES: true *) 30 | (* ENSURES: append(S1,S2) returns a stack with S1 31 | * appended to S2 *) 32 | fun append (S1 : stack, S2 : stack) = S1 @ S2 33 | 34 | (* find : stack * (stacktype -> bool) -> stack option *) 35 | (* REQUIRES: true *) 36 | (* ENSURES: find (S,p) returns SOME(S') if there exists 37 | * a largest substack S' of S where the first 38 | * element x to be popped off of S' satisfies 39 | * p x and NONE if no such element can be found *) 40 | fun find ([] : stack, p : stacktype -> bool) : stack option = NONE 41 | | find (x::xs, p) = if p x 42 | then SOME(x::xs) 43 | else find (xs, p) 44 | 45 | (* flip : stack -> stack *) 46 | (* REQUIRES: true *) 47 | (* ENSURES: flip S returns S', where S' is the 48 | * stack S flipped upside down like a 49 | * stack of pancakes *) 50 | fun flip (S : stack) : stack = List.rev(S) 51 | end 52 | 53 | structure TestStackImp = 54 | struct 55 | 56 | structure TTest : TYPEDEF = 57 | struct 58 | type t = int 59 | end 60 | 61 | structure TestStack : STACK = Stack(TTest) 62 | open TestStack 63 | 64 | fun testStackComplete () : bool = 65 | let 66 | val [] = empty() 67 | val [5] = push(empty(),5) 68 | val [1,2] = push(push(empty(),2),1) 69 | val (5,[]) = pop(push(empty(),5)) 70 | val (1,[2]) = pop(push(push(empty(),2),1)) 71 | val [5] = append(push(empty(),5),empty()) 72 | val [] = append(empty(),empty()) 73 | val [3,4] = append(push(empty(),3),push(empty(),4)) 74 | val NONE = find (empty(),(fn x => true)) 75 | val NONE = find (push(empty(),5), (fn x => (x mod 2 = 0))) 76 | val SOME([5]) = find (push(empty(),5), (fn x => (x=5))) 77 | val SOME([2,3]) = find (push(push(push(empty(),3),2),1), (fn x => (x=2))) 78 | val [] = flip(empty()) 79 | val [1] = flip(push(empty(),1)) 80 | val [3,2] = flip(push(push(empty(),3),2)) 81 | in 82 | true 83 | end 84 | 85 | val true = testStackComplete() 86 | 87 | end 88 | -------------------------------------------------------------------------------- /hw/12/code/lazy.sml: -------------------------------------------------------------------------------- 1 | structure Lazy : LAZY = 2 | struct 3 | datatype lazylist = datatype LazyList.lazylist 4 | structure LazyList = LazyList 5 | 6 | (* Remove this when you're done to make sure you didn't miss anything *) 7 | exception Unimplemented 8 | 9 | (* Task 3.1 *) 10 | (* lazy_merge : ('a * 'a -> order) -> 'a lazylist -> 11 | * 'a lazylist -> 'a lazylist *) 12 | (* REQUIRES: L1 and L2 are cmp-sorted *) 13 | (* ENSURES: lazy merge cmp L1 L2 evaluates to a cmp-sorted lazy list 14 | * such that show n (lazy merge cmp L1 L2) consists of the 15 | * n smallest elements from the set of items belonging to L1 or L2 *) 16 | fun lazy_merge cmp (L1 as Cons(a1, f1)) (L2 as Cons(a2, f2)) = 17 | case cmp(a1, a2) of 18 | GREATER => Cons(a2, (fn () => lazy_merge cmp L1 (f2()))) 19 | | _ => Cons(a1, (fn () => lazy_merge cmp (f1()) L2)) 20 | 21 | (* Task 3.2 *) 22 | (* combine : ('a * 'a -> order) -> 'a lazylist lazylist -> 'a lazylist *) 23 | (* REQUIRES: L is a laxy list of cmp-sorted lazy lists and the lazy list 24 | * consisting of the first elements of each lazy list in L is also 25 | * cmp-sorted *) 26 | (* ENSURES: combine L evaluates to a cmp-sorted lazy list such that 27 | * show n (combine cmp L) consists of the n smallest elements from the 28 | * set of items belonging to the lazy lists in L *) 29 | fun combine cmp (Cons(Cons(x, xs), R)) = 30 | let 31 | val Cons(y, ys) = R() 32 | in 33 | Cons(x, (fn () => combine cmp (Cons((lazy_merge cmp (xs()) y), ys)))) 34 | end 35 | 36 | (* Task 3.3 *) 37 | (* pairsHelper : (int * int) lazylist *) 38 | (* REQUIRES: true *) 39 | (* ENSURES: pairsHelper L evalutes to the lazy list of the first value 40 | * in each pair in L incremented by one *) 41 | fun pairsHelper (Cons((x,y),R)) = 42 | Cons((x+1,y), (fn () => pairsHelper (R()))) 43 | 44 | 45 | (* pairs : (int * int) lazylist *) 46 | val pairs = combine 47 | (fn ((a1,a2),(b1,b2)) => 48 | case (Int.compare(a1 + a2, b1 + b2), 49 | Int.compare(a1, b1)) of 50 | (LESS, _) => LESS 51 | | (GREATER, _) => GREATER 52 | | (_, GREATER) => GREATER 53 | | (_, _) => EQUAL) 54 | (LazyList.iterate pairsHelper 55 | (LazyList.iterate (fn (x,y) => (x,y+1)) (0,0))) 56 | 57 | end 58 | 59 | structure LazyTests = 60 | struct 61 | open LazyList 62 | open Lazy 63 | 64 | (* Tests for lazy_merge *) 65 | val L1 = LazyList.iterate (fn x => x + 1) 0 66 | val L2 = LazyList.iterate (fn x => x + 2) 0 67 | val [0,0,1,2,2,3,4,4,5,6] = 68 | (show 10 (lazy_merge Int.compare L1 L2)) 69 | 70 | (* Tests for combine *) 71 | fun combineTest (Cons(x,R)) = 72 | Cons(x+2, (fn () => combineTest (R()))) 73 | val [0,1,2,2,3,3,4,4,4,5] = 74 | show 10 (combine Int.compare (LazyList.iterate combineTest 75 | (LazyList.iterate (fn x => x+1) 0))) 76 | 77 | (* Tests for pairs *) 78 | val [(0,0),(0,1),(1,0),(0,2),(1,1),(2,0),(0,3),(1,2),(2,1),(3,0)] = 79 | show 10 pairs 80 | 81 | end 82 | -------------------------------------------------------------------------------- /hw/10/code/lib/makeplane.sml: -------------------------------------------------------------------------------- 1 | functor MakePlane(P : PLANEARGS) :> SPACE where Seq = P.Seq 2 | and Scalar = P.Scalar = 3 | struct 4 | structure Seq = P.Seq 5 | structure Scalar = P.Scalar 6 | 7 | type scalar = Scalar.scalar 8 | 9 | datatype coord = Coord of scalar * scalar 10 | datatype vector = Vec of scalar * scalar 11 | 12 | type point = coord 13 | type vec = vector 14 | 15 | infixr 3 ++ 16 | 17 | (* v1 ++ v2 evaluates to the sum of the vectors *) 18 | fun (Vec (x1,y1)) ++ (Vec (x2,y2)) : vec = 19 | Vec (Scalar.plus (x1, x2), Scalar.plus (y1, y2)) 20 | 21 | infixr 4 ** 22 | 23 | (* v ** c evaluates to the scalar product of v with c *) 24 | fun (Vec (x,y) : vec) ** (c : scalar): vec = 25 | Vec (Scalar.times (x, c), Scalar.times (y, c)) 26 | 27 | infixr 3 --> 28 | (* X --> Y is the vector from X to Y 29 | * computed by Y - X componentwise 30 | *) 31 | fun (Coord (x1, y1) : point) --> (Coord (x2, y2) : point) : vec = 32 | Vec (Scalar.minus (x2, x1), Scalar.minus (y2, y1)) 33 | 34 | infixr 3 // 35 | (* v // c evaluates to the scalar product of v with (1/c) *) 36 | fun (v : vec) // (c : scalar) : vec = v ** (Scalar.invert c) 37 | 38 | (* The origin point *) 39 | val origin : point = Coord (Scalar.fromRatio (0,1), Scalar.fromRatio (0,1)) 40 | 41 | (* Computes the cartesian coordinates of the given point *) 42 | fun cartcoord (Coord (x, y) : point) : scalar * scalar = (x,y) 43 | 44 | (* Return a point in 2D space with the given Cartesian coordinates *) 45 | fun fromcoord ((x, y) : scalar * scalar) = Coord (x, y) 46 | 47 | (* Computes the distance between the argument points *) 48 | fun distance (Coord x) (Coord y) = P.distance x y 49 | 50 | (* Computes the magnitude of the given vector *) 51 | fun mag (Vec (x, y) : vec) : scalar = distance (Coord (x, y)) origin 52 | 53 | fun vecToString (Vec (x,y) : vec) = 54 | "(" ^ Scalar.toString x ^ ", " ^ Scalar.toString y ^ ")" 55 | 56 | fun pointToString (Coord (x,y) : point) = 57 | "(" ^ Scalar.toString x ^ ", " ^ Scalar.toString y ^ ")" 58 | 59 | (* Tests two points for equality *) 60 | fun pointEqual (Coord (x1, y1) : point, Coord (x2, y2) : point) : bool = 61 | case (Scalar.compare(x1,x2), Scalar.compare(y1,y2)) of 62 | (EQUAL,EQUAL) => true 63 | |_ => false 64 | 65 | fun displace (Coord (x,y) : point, Vec (v1, v2) : vec) : point = 66 | Coord (Scalar.plus (x, v1), Scalar.plus (y, v2)) 67 | 68 | val zero : vec = Vec (Scalar.zero,Scalar.zero) 69 | 70 | fun unitVec (V as Vec v : vec) : vec = V ** (Scalar.invert (mag V)) 71 | 72 | fun sum (f : 'a -> vec) : 'a Seq.seq -> vec = Seq.mapreduce f zero op++ 73 | 74 | (* compute the mid-point of a line that connects two points *) 75 | fun midpoint (Coord (x1, y1) : point) (Coord (x2, y2) : point) : point = 76 | Coord (Scalar.divide (Scalar.plus (x1, x2), Scalar.fromInt 2), 77 | Scalar.divide (Scalar.plus (y1, y2), Scalar.fromInt 2)) 78 | 79 | (* Compute the point corresponding to the dispacement by the given vector 80 | * from the origin 81 | *) 82 | fun head (v : vec) : point = displace (origin, v) 83 | end 84 | -------------------------------------------------------------------------------- /lab/03/code/lab03.sml: -------------------------------------------------------------------------------- 1 | (* you can remove this defintion when you're done to make sure you didn't 2 | * miss any functions 3 | *) 4 | exception Unimplemented 5 | 6 | (* Task 2.1 *) 7 | (* append : int list * int list -> int list *) 8 | (* REQUIRES: L1 and L2 are type int list *) 9 | (* ENSURES: Appends L1 to L2 *) 10 | fun append ([] : int list, L2 : int list) : int list = L2 11 | | append (x::L : int list, L2 : int list) : int list = append(L, x::L2) 12 | 13 | (* Task 3.1 *) 14 | (* reverse : int list -> int list *) 15 | (* REQUIRES: L is type int list *) 16 | (* ENSURES: reverses L *) 17 | fun reverse ([] : int list) : int list = [] 18 | | reverse (x::L : int list) : int list = reverse(L) @ [x] 19 | 20 | (* moveFront' : int list -> int list *) 21 | (* REQUIRES: L1 and L2 are type int list *) 22 | (* ENSURES: move first element of L2 to front of L1 *) 23 | fun moveFront (L1 : int list, [] : int list) : int list = L1 24 | | moveFront(L1 : int list, x::L : int list) : int list = moveFront(x::L1, L) 25 | 26 | (* Task 3.3 *) 27 | (* moveFront' : int list -> int list *) 28 | (* REQUIRES: L1 and L2 are type int list *) 29 | (* ENSURES: move first element of L2 to front of L1 *) 30 | fun moveFront (L1 : int list, [] : int list) : int list = L1 31 | | moveFront(L1 : int list, x::L : int list) : int list = moveFront(x::L1, L) 32 | 33 | (* reverse' : int list -> int list *) 34 | (* REQUIRES: L is type int list *) 35 | (* ENSURES: reverses L *) 36 | fun reverse' ([] : int list) : int list = [] 37 | | reverse' (x::L : int list) : int list = moveFront([x],L) 38 | 39 | 40 | fun fib (0 : int) : int = 1 41 | | fib 1 = 1 42 | | fib n = fib (n-1) + fib (n-2) 43 | 44 | (* Task 5.1*) 45 | (* sumPair : int * int -> int *) 46 | (* REQUIRES: n and m are type int *) 47 | (* ENSURES: sumPair(x,y) evalutes to x+y *) 48 | fun sumPair (n : int, m : int) : int = n + m 49 | 50 | (* fibber : int -> int * int *) 51 | (* REQUIRES: n>=0 *) 52 | (* ENSURES: fibber(n) returns (fib(n), fib(n+1)) *) 53 | fun fibber (0 : int) : int * int = (0, 1) 54 | | fibber (n : int) : int * int = (sumPair(fibber(n-2)), sumPair(fibber(n-1))) 55 | 56 | (* Task 6.1 *) 57 | (* merge : int list * int list -> int list *) 58 | (* REQUIRES: L1 and L2 are sorted *) 59 | (* ENSURES: merge(L1, L2) merges L1 and L2 and is sorted *) 60 | fun merge (L1 : int list, [] : int list) : int list = L1 61 | | merge ([] : int list, L2 : int list) : int list = L2 62 | | merge (x::L1 : int list, y::L2 : int list) : int list = 63 | if x < y 64 | then x::merge(L1, y::L2) 65 | else y::merge(x::L1, L2) 66 | 67 | (* Task 7.1 *) 68 | (* evens : int list -> int list *) 69 | (* REQUIRES: L is type int list *) 70 | (* ENSURES: evens(L) evalutes to a list of the even numbers in L *) 71 | fun evens ([] : int list) : int list = [] 72 | | evens (x::L : int list) : int list = 73 | if x mod 2 = 0 74 | then x::evens(L) 75 | else evens(L) 76 | 77 | (* Task 7.2 *) 78 | (* DOCUMENT THIS FUNCTION *) 79 | fun bitAnd (L1 : int list, L2 : int list) : int list = 80 | raise Unimplemented 81 | 82 | (* Task 7.3 *) 83 | (* DOCUMENT THIS FUNCTION *) 84 | fun interleave (L1 : int list, L2 : int list) : int list = 85 | raise Unimplemented 86 | 87 | -------------------------------------------------------------------------------- /hw/10/code/lib/transcripts.sml: -------------------------------------------------------------------------------- 1 | structure RealArgs : BHArgs = 2 | struct 3 | val prefix = "real" 4 | val thresh : IntInf.int * IntInf.int = (1,2) 5 | structure BB : BOX = BoundingBox(MakePlane(RealPlaneArgs(VectorSeq))) 6 | structure Mech : MECHANICS = Mechanics(BB.Plane) 7 | end 8 | 9 | structure RatArgs : BHArgs = 10 | struct 11 | val prefix = "rat" 12 | val thresh : IntInf.int * IntInf.int = (1,2) 13 | structure BB : BOX = BoundingBox(MakePlane(RatPlaneArgs(VectorSeq))) 14 | structure Mech : MECHANICS = Mechanics(BB.Plane) 15 | end 16 | 17 | (* given a universe, this functor represents the solar system in it. when 18 | go is forced, it runs barneshut in that universe with various subsets of 19 | the solar system and produces transcript files in the current working 20 | directory. these canned examples are small enough that an arbitrary 21 | precision rational implementation of the universe should allow BH to 22 | terminate on them with in a few minutes 23 | *) 24 | functor Transcripts (BH : BARNESHUT) = 25 | struct 26 | structure Plane = BH.Args.BB.Plane 27 | structure Solars = Solars(BH) 28 | structure Sim = Simulation(BH) 29 | 30 | (* suspend this computation so that you get to choose when it happens *) 31 | fun go () = 32 | let 33 | (* helpers to make input *) 34 | fun prep solars bef (x,y) = 35 | (x, 36 | solars, 37 | String.concatWith "." [BH.Args.prefix, bef, y, "auto", "txt"]) 38 | 39 | fun days (x : int) = (x+1, (Int.toString(x+1)) ^ "day") 40 | 41 | (* some canned input--small enough to run with rationals, too*) 42 | val secs_in_day = (Plane.Scalar.fromInt 864000) 43 | 44 | val onebody_list = map (prep Solars.one_body "onebody") 45 | [(1,"1day"), (14,"2weeks"), (365,"1yr")] 46 | 47 | val twobody_list = map (prep Solars.two_body "twobody") 48 | (List.tabulate(6,days)) 49 | 50 | val system_list = map (prep Solars.solar_system "system") 51 | (List.tabulate(2,days)) 52 | 53 | val all = onebody_list @ twobody_list @ system_list 54 | val all' = if BH.Args.prefix = "real" then 55 | let 56 | val one1000 = (prep Solars.one_body "onebody") (days 1000) 57 | val two1000 = (prep Solars.two_body "twobody") (days 1000) 58 | val sys1000 = (prep Solars.solar_system "system") (days 1000) 59 | in all @ [one1000, sys1000, two1000] end 60 | else all 61 | 62 | (* how to run BH on the input---notice that this won't run naive *) 63 | fun dorun (num_days, bod, name) = 64 | let 65 | val () = print ("made " ^ name ^ " ...") 66 | val t1 = Time.now (); 67 | val () = Sim.runBH bod secs_in_day num_days name 68 | val t2 = Time.now (); 69 | val delta = Time.-(t2,t1) 70 | val () = print (" in " ^ Time.toString delta ^ " seconds\n") 71 | in 72 | () 73 | end 74 | in 75 | (* actually run BH on the input and make transcripts *) 76 | List.app dorun all' 77 | end 78 | end 79 | -------------------------------------------------------------------------------- /lab/05/solutions/lab05-sol.sml: -------------------------------------------------------------------------------- 1 | (***** Section 3 Higher Order Functions *****) 2 | 3 | (* Task 3.1 *) 4 | val double: int -> int = fn x => x * 2 5 | val quadruple : int -> int = fn x => double (double x) 6 | 7 | (* Task 3.2 *) 8 | fun thenAddOne ((f:int -> int), (x:int)) : int = 9 | f x + 1 10 | 11 | val 5 = thenAddOne(double, 2) 12 | val 13 = thenAddOne(quadruple, 3) 13 | val ~1 = thenAddOne(fn x => ~x, 2) 14 | 15 | (* doubleList and quadrupleList reproduced for your convenience *) 16 | 17 | fun doubleList ([] : int list): int list = [] 18 | | doubleList (x::xs) = 19 | (double x)::(doubleList xs) 20 | 21 | fun quadrupleList ([]:int list): int list = [] 22 | | quadrupleList (x::xs) = 23 | (quadruple x)::(quadrupleList xs) 24 | 25 | (* Task 3.3 *) 26 | 27 | (* mapList : ('a -> 'b) * 'a list -> 'b list *) 28 | (* REQUIRES: f is total *) 29 | (* ENSURES: mapList (f,[x1, ..., xi]) == [f x1, ..., f xi] *) 30 | fun mapList (f: 'a -> 'b, [] : 'a list): 'b list = [] 31 | | mapList (f, x::xs) = (f x)::(mapList (f, xs)) 32 | 33 | (* Task 3.4 *) 34 | 35 | (* mapList' : ('a -> 'b) -> ('a list -> 'b list) *) 36 | (* REQUIRES: f is total *) 37 | (* ENSURES: mapList f [x1, ..., xi] == [f x1, ..., f xi] *) 38 | fun mapList' (f : 'a -> 'b) (L : 'a list) : 'b list = 39 | case L of 40 | [] => [] 41 | | x::xs => (f x)::(mapList' f xs) 42 | 43 | (* Task 3.5 *) 44 | val [] = mapList(double, []) 45 | val [] = mapList(quadruple, []) 46 | val [2,4,6] = mapList(double, [1,2,3]) 47 | val [4,8,12] = mapList(quadruple, [1,2,3]) 48 | val [15,150] = mapList(fn x => x + 10, [5, 140]) 49 | 50 | val [] = mapList' double [] 51 | val [4,8,12] = mapList' quadruple [1,2,3] 52 | val [~2,4,~5] = mapList' (fn x => ~x) [2,~4,5] 53 | 54 | 55 | (***** Section 4 Options ******) 56 | (* Task 4.1 *) 57 | 58 | (* findOdd: int list -> int option *) 59 | (* REQUIRES : true *) 60 | (* ENSURES : findOdd(L) returns SOME(x) iff 61 | * there is at least one odd number x in L *) 62 | fun findOdd([] : int list): int option = NONE 63 | | findOdd(x::xs) = case x mod 2 of 64 | 1 => SOME x 65 | | _ => findOdd xs 66 | 67 | val NONE = findOdd [] 68 | val NONE = findOdd [2,4,6] 69 | (* Note for these we're just testing that we get back SOME. 70 | * so saying val SOME x would be sufficient as well *) 71 | val SOME 1 = findOdd [1,3,5] 72 | val SOME 3 = findOdd [2,3,4,5,6,7,8] 73 | 74 | (* subsetSumCert provided for your convenience *) 75 | fun subsetSumCert (nil : int list, s : int): bool * int list = (s=0, nil) 76 | | subsetSumCert (x::xs, s) = 77 | case subsetSumCert (xs, s-x) of 78 | (true, l1) => (true, x::l1) 79 | | (false, _) => subsetSumCert (xs,s) 80 | 81 | (* Task 4.2 *) 82 | 83 | (* subsetSumOption : int list * int -> int list option *) 84 | (* REQUIRES: true *) 85 | (* ENSURES: subsetSumOption(l,s) == SOME l' iff l' is a sublist 86 | * of l that sums to s and NONE if no such l' exists *) 87 | fun subsetSumOption (l : int list, 0 : int) : int list option = SOME [] 88 | | subsetSumOption ([], _) = NONE 89 | | subsetSumOption (x::xs, s) = 90 | case subsetSumOption(xs, s-x) of 91 | SOME(l) => SOME(x::l) 92 | | NONE => subsetSumOption(xs, s) 93 | 94 | val NONE = subsetSumOption([],1) 95 | val NONE = subsetSumOption([1,2,3],~1) 96 | val SOME [] = subsetSumOption([], 0) 97 | val SOME [] = subsetSumOption([1,2,3,4],0) 98 | -------------------------------------------------------------------------------- /lab/09/solutions/code/TreeSets.sml: -------------------------------------------------------------------------------- 1 | structure TreeSets : INTSET = 2 | struct 3 | exception NotYetImplemented 4 | exception IntentionallyUnimplemented 5 | 6 | exception NotInSet 7 | 8 | datatype 'a tree = Empty | Node of 'a tree * 'a * 'a tree 9 | 10 | type set = int tree 11 | 12 | val empty = fn () => Empty 13 | 14 | fun find (n : int) (Empty : set) = false 15 | | find (n) (Node(L, x, R)) = 16 | (case Int.compare (n, x) of 17 | EQUAL => true 18 | | GREATER => find n R 19 | | LESS => find n L) 20 | 21 | 22 | fun insert (n : int) (Empty : set) = Node(Empty, n, Empty) 23 | | insert (n) (s2 as Node(L, x, R)) = 24 | case n = x of 25 | true => s2 26 | | false => if(n < x) 27 | then Node(insert n L, x, R) 28 | else Node(L, x, insert n R) 29 | 30 | (* delete : int -> set -> set 31 | * requires: true 32 | * ensures: raises IntentiallyUnimplemented 33 | * 34 | * You don't have to implement delete; though once you learn mutually recursive 35 | * functions, you'll be able to. 36 | * 37 | * Luckily, you can write union, intersection, and difference without delete! 38 | *) 39 | fun delete (n : int) (s : set) = raise IntentionallyUnimplemented 40 | 41 | fun union (Empty : set) (s2 : set) = s2 42 | | union (Node(L, x, R)) (s2) = 43 | if (find x s2) then union R (union L s2) 44 | else union R (union L (insert x s2)) 45 | 46 | fun intersection (Empty : set) (s2 : set) = Empty 47 | | intersection (s1) (Empty) = Empty 48 | | intersection (Node(L, x, R)) (s2) = 49 | if (find x s2) 50 | then insert x (union (intersection L s2) (intersection R s2)) 51 | else (union (intersection L s2) (intersection R s2)) 52 | 53 | fun difference (Empty : set) (s2 : set) = Empty 54 | | difference (s1: set) (Empty : set) = s1 55 | | difference (s1) (Node(L,x,R)) = 56 | if (find x s1) 57 | then union (difference s1 L) (difference s1 R) 58 | else insert x (union (difference s1 L) (difference s1 R)) 59 | 60 | end 61 | 62 | structure TestTreeSets = 63 | struct 64 | (* 'open' brings everything in the TreeSet namespace into this structure. 65 | * We can now use 'insert' instead of 'TreeSets.insert' 66 | *) 67 | open TreeSets 68 | 69 | (* t = <5, 6> *) 70 | val t = empty() 71 | val t = insert 5 t 72 | val t = insert 6 t 73 | val true = find 5 t 74 | val true = find 6 t 75 | 76 | (* r = <7> *) 77 | val r = insert 7 (empty()) 78 | val true = find 7 r 79 | 80 | (* s = <5> *) 81 | val s = insert 5 (empty()) 82 | val true = find 5 s 83 | 84 | 85 | (* Test union *) 86 | val q = union r t 87 | val true = find 5 q 88 | val true = find 6 q 89 | val true = find 7 q 90 | val false = find 8 q 91 | 92 | (* Test intersection *) 93 | val i = intersection r t 94 | val false = find 6 i 95 | val false = find 5 i 96 | val false = find 7 i 97 | 98 | val i = intersection s t 99 | val true = find 5 i 100 | val false = find 6 i 101 | val false = find 7 i 102 | 103 | (* Test difference *) 104 | val d = difference r t 105 | val true = find 6 d 106 | val true = find 5 d 107 | val true = find 7 d 108 | 109 | val d = difference t s 110 | val true = find 5 d 111 | val true = find 6 d 112 | val false = find 7 d 113 | 114 | end 115 | -------------------------------------------------------------------------------- /hw/02/code/hw02-proof-templates.tex: -------------------------------------------------------------------------------- 1 | \documentclass[11pt]{article} 2 | 3 | \usepackage{amsmath} 4 | \usepackage{amssymb} 5 | \usepackage{fancyhdr} 6 | 7 | \oddsidemargin0cm 8 | \topmargin-2cm %I recommend adding these three lines to increase the 9 | \textwidth16.5cm %amount of usable space on the page (and save trees) 10 | \textheight23.5cm 11 | 12 | \newcommand{\question}[2] {\vspace{.25in} \hrule\vspace{0.5em} 13 | \noindent{\bf #1: #2} \vspace{0.5em} 14 | \hrule \vspace{.10in}} 15 | \renewcommand{\part}[1] {\vspace{.10in} {\bf (#1)}} 16 | 17 | \newcommand{\sml}[1]{\texttt{#1}} 18 | \newcommand{\hasType}[2]{#1: #2} 19 | \newcommand{\step}{\ensuremath{\Rightarrow}} 20 | \newcommand{\stepstar}{\ensuremath{\step ^*}} 21 | \newcommand{\stepplus}{\ensuremath{\step ^+}} 22 | 23 | \newcommand{\myname}{Your Name} 24 | \newcommand{\myandrew}{your-andrew-id@andrew.cmu.edu} 25 | \newcommand{\myhwnum}{2} 26 | 27 | \pagestyle{fancyplain} 28 | \lhead{\fancyplain{}{\textbf{HW\myhwnum}}} % Note the different brackets! 29 | \rhead{\fancyplain{}{\myname\\ \myandrew}} 30 | \chead{\fancyplain{}{15-150}} 31 | 32 | \begin{document} 33 | 34 | \medskip 35 | 36 | \thispagestyle{plain} 37 | \begin{center} % Center the following lines 38 | {\Large 15-150 Assignment \myhwnum} \\ 39 | \myname \\ 40 | \myandrew \\ 41 | Day Month Year\\ 42 | \end{center} 43 | 44 | \question{Section}{2} 45 | \medskip 46 | \noindent\part{6} 47 | 48 | \begin{align*} 49 | &\quad\;\; \sml{decimal (5 + 5)}\\ 50 | &= \ldots && \text{Justifications} \\ 51 | &= [0, 1] 52 | \end{align*} 53 | 54 | \medskip 55 | \noindent\part{7} 56 | 57 | \begin{align*} 58 | &\quad\;\; \sml{decimal (5 + 5)}\\ 59 | &\stepstar \ldots \\ 60 | &\stepstar [0, 1] 61 | \end{align*} 62 | 63 | \question{Section}{4} 64 | \medskip 65 | \noindent\part{1} 66 | \paragraph{Theorem:} 67 | For all integer lists \sml{L} such that \sml{L} is \sml{all zeroes}, \sml{eval L} = \sml{0}.\\\\ 68 | 69 | \noindent The proof is by structural induction on \sml{L}.\\\\ 70 | \textbf{Base Case:} \quad Prove for $\sml{L}=\sml{[]}$\\ 71 | \textbf{Need to show:} \\ 72 | Showing: 73 | \begin{align*} 74 | &\quad\;\; \sml{eval []}\\ 75 | & \stepstar \ldots && \text{Justifications} 76 | \end{align*} 77 | \\\\ 78 | \textbf{Inductive Step:} \quad Prove for \sml{L} = \sml{x::R}\\ 79 | \textbf{Inductive Hypothesis:} \\ 80 | \textbf{Need to show:} \\ 81 | Showing: 82 | \begin{align*} 83 | &\quad\;\; \sml{eval (x::R)}\\ 84 | & \stepstar \ldots && \text{Justifications} 85 | \end{align*} 86 | \\ 87 | By the Base Case and Inductive Step, the claim is true.\\\\ 88 | 89 | \noindent\part{2}\\ 90 | \paragraph{Theorem:} 91 | For all natural numbers \sml{n}, \sml{sumOdd n} = \sml{n*n}.\\\\ 92 | 93 | \noindent The proof is by structural induction on \sml{n}. 94 | 95 | \noindent\textbf{Base Case:}\quad Prove for \sml{n=0}.\\ 96 | \textbf{Need to Show:} \\ 97 | Showing: 98 | \begin{align*} 99 | &\quad\;\; \sml{sumOdd 0}\\ 100 | &= \ldots && \text{Justifications} 101 | \end{align*} 102 | \\\\ 103 | \noindent\textbf{Induction Step:} \quad Prove for \sml{n+1}\\ 104 | \textbf{Inductive Hypothesis:} \\ 105 | \textbf{Need to show:} \\ 106 | Showing: 107 | \begin{align*} 108 | &\quad\;\; \sml{sumOdd (n+1)}\\ 109 | &= \ldots && \text{Justifications} 110 | \end{align*} 111 | \\ 112 | Thus we have shown for all $n$, \sml{sumOdd(n)} = \sml{n*n}.\\ 113 | \end{document} 114 | -------------------------------------------------------------------------------- /lab/02/code/lab02.sml: -------------------------------------------------------------------------------- 1 | (* TASK 2.1 *) 2 | 3 | (* summ : int -> int *) 4 | (* REQUIRES: n >= 0 *) 5 | (* ENSURES: summ n returns the sum of the integers 0 through n. *) 6 | fun summ (0 : int) : int = 0 7 | | summ n = n + summ (n - 1) 8 | 9 | (* Tests for summ *) 10 | val 0 = summ 0 11 | val 6 = summ 3 12 | 13 | (* TASK 2.2 *) 14 | 15 | (* double : int -> int *) 16 | (* REQUIRES: n >= 0 *) 17 | (* ENSURES: double n evaluates to 2 * n.*) 18 | fun double (0 : int) : int = 0 19 | | double n = 2 + double (n - 1) 20 | 21 | (* Tests for double *) 22 | val 0 = double 0 23 | val 4 = double 2 24 | 25 | (* square : int -> int *) 26 | (* REQUIRES: n >= 0.*) 27 | (* ENSURES: square n evaluates to n * n.*) 28 | fun square (0 : int) : int = 0 29 | | square n = square (n - 1) + double (n) - 1 30 | 31 | (* Tests for square *) 32 | val 0 = square 0 33 | val 9 = square 3 34 | 35 | (* TASK 2.3 *) 36 | 37 | (* divisibleByThree : int -> bool *) 38 | (* REQUIRES: n >= 0.*) 39 | (* ENSURES: divisibleByThree n evaluates to true iff n is a multiple of 3.*) 40 | fun divisibleByThree (0 : int) : bool = true 41 | | divisibleByThree 1 = false 42 | | divisibleByThree 2 = false 43 | | divisibleByThree n = divisibleByThree (n - 3) 44 | 45 | (* Tests for divisibleByThree *) 46 | val true = divisibleByThree 0 47 | val false = divisibleByThree 2 48 | val true = divisibleByThree 6 49 | val false =divisibleByThree 7 50 | 51 | (* TASK 4.1 *) 52 | 53 | (* GCD : int -> int *) 54 | (* GCD: int * int -> int *) 55 | (* REQUIRES: m, n >= 0 *) 56 | (* ENSURES: GCD (m, n) returns the g.c.d. of m and n *) 57 | fun GCD (m: int, 0): int = m 58 | | GCD (0, n: int): int = n 59 | | GCD (m: int, n: int): int = 60 | if m > n then GCD(m mod n, n) else GCD(m, n mod m) 61 | 62 | (* evenP : int -> bool *) 63 | (* REQUIRES: n >= 0 *) 64 | (* ENSURES: evenP n evaluates to true iff n is even. *) 65 | fun evenP (0 : int) : bool = true 66 | | evenP 1 = false 67 | | evenP n = evenP (n - 2) 68 | 69 | (* Tests for evenP *) 70 | val true = evenP 0 71 | val false = evenP 1 72 | val true = evenP 12 73 | val false = evenP 27 74 | 75 | (* oddP : *) 76 | (* REQUIRES: n >= 0 *) 77 | (* ENSURES: oddP n evaluates to true iff n is odd. *) 78 | fun oddP (0 : int) : bool = false 79 | | oddP 1 = true 80 | | oddP n = oddP (n - 2) 81 | 82 | (* stein : int * int -> int *) 83 | (* REQUIRES: m, n > 0 *) 84 | (* ENSURES: stein(m,n) returns the g.c.d. of m and n. *) 85 | fun stein(m,n) = 86 | if m=n then m else 87 | if m mod 2 = 0 88 | then 89 | if n mod 2 = 0 90 | then 2 * stein(m div 2, n div 2) 91 | else stein(m div 2, n) 92 | else if n mod 2 = 0 93 | then stein(m, n div 2) 94 | else if n>m 95 | then stein(m, (n-m) div 2) 96 | else stein((m-n) div 2, n) 97 | 98 | 99 | (* TASK 5.1 *) 100 | 101 | (* stein' : int * int -> int *) 102 | (* REQUIRES: m, n > 0 *) 103 | (* ENSURES: stein'(m,n) returns the g.c.d. of m and n. *) 104 | fun stein'(m,n) = 105 | if m=n then m else 106 | case (evenP(m), evenP(n)) for 107 | (true, true) = 2 * stein(m div 2, n div 2) 108 | (true, false) = (true, true) = 2 * stein(m div 2, n div 2) 109 | (false, true) = stein(m, n div 2) 110 | (false, false) = 111 | if n>m 112 | then stein(m, (n-m) div 2) 113 | else stein((m-n) div 2, n) 114 | -------------------------------------------------------------------------------- /lab/04/code/lab04.sml: -------------------------------------------------------------------------------- 1 | (* ---------------------------------------------------------------------- *) 2 | (* Functions provided by the course staff. *) 3 | 4 | (* max : int * int -> int 5 | * REQUIRES: true 6 | * ENSURES: max (x, y) ==> the greater of x or y 7 | * 8 | * Examples: 9 | * max (1, 4) ==> 4 10 | * max (~4, 0) ==> 0 11 | * max (2, 2) ==> 2 12 | *) 13 | fun max (n1 : int, n2 : int) : int = 14 | case Int.compare(n1,n2) 15 | of LESS => n2 16 | | _ => n1 17 | 18 | val 4 = max (1, 4) 19 | val 0 = max (~4, 0) 20 | val 2 = max (2, 2) 21 | 22 | (* split : int list -> int list * int * int list 23 | * REQUIRES: l is non-empty 24 | * ENSURES: there exist l1,x,l2 such that 25 | * split l == (l1,x,l2) and 26 | * l == l1 @ x::l2 and 27 | * length(l1) and length(l2) differ by no more than 1 28 | *) 29 | fun split ([] : int list) : (int list * int * int list) = 30 | raise Fail "split should never be called on an empty list" 31 | | split l = 32 | let 33 | val midlen = (length l) div 2 34 | val front = (List.take (l,midlen)) 35 | 36 | (* because we round down, if the list is non-empty, this 37 | * has at least one thing in it 38 | *) 39 | val x :: back = (List.drop (l,midlen)) 40 | in 41 | (front, x, back) 42 | end 43 | 44 | (* ---------------------------------------------------------------------- *) 45 | (* Functions you, the student, need to implement. *) 46 | 47 | (***** Section 2: Depth *****) 48 | 49 | datatype tree = 50 | Empty 51 | | Node of (tree * int * tree) 52 | 53 | (* Task 2.1 *) 54 | (* tree : tree -> int *) 55 | (* REQUIRES: true *) 56 | (* ENSURES: depth(t) evaluates to the depth of t *) 57 | fun depth (Empty : tree) : int = 0 58 | | depth (Node (l, x, r) : tree) : int = 1 + max(depth(l), depth(r)) 59 | 60 | (* ---------------------------------------------------------------------- *) 61 | 62 | (***** Section 3: Lists to Trees *****) 63 | 64 | (* Task 3.1 *) 65 | (* lsitToTree : int list -> tree *) 66 | (* REQUIRES: true *) 67 | (* ENSURES: listToTree(l) transforms l to a balanced tree *) 68 | fun listToTree ([] : int list) : tree = Empty 69 | | listToTree (l : int list) : tree = 70 | let val (l1, x, l2) = split(l) 71 | in Node(listToTree(l1), x, listToTree(l2)) 72 | end 73 | 74 | (* ---------------------------------------------------------------------- *) 75 | 76 | (***** Section 4: Reverse *****) 77 | 78 | (* treeToList : tree -> int list 79 | * REQUIRES: true 80 | * ENSURES: returns a list of the elements in the tree, 81 | * ordered by an in-order traversal 82 | *) 83 | fun treeToList (Empty : tree) : int list = [] 84 | | treeToList (Node(l,x,r)) = treeToList l @ (x :: (treeToList r)) 85 | 86 | (* Task 4.1 *) 87 | (* revT : tree -> tree *) 88 | (* REQUIRES true *) 89 | (* ENSURES revT(t) reverses the tree t *) 90 | fun revT (Empty : tree) : tree = Empty 91 | | revT (Node(l, x, r) : tree) : tree = Node(revT(r), x, revT(l)) 92 | 93 | (* ---------------------------------------------------------------------- *) 94 | 95 | (***** Section 5: Binary Search *****) 96 | 97 | (* Task 5.1 *) 98 | 99 | fun binarySearch (Empty : tree, x : int) : bool = false 100 | | binarySearch (Node(l, y, r) : tree , x : int) = 101 | case Int.compare(y, x) of 102 | GREATER => binarySearch (l, x) 103 | | EQUAL => true 104 | | LESS => binarySearch(r, x) 105 | -------------------------------------------------------------------------------- /hw/11/code/graphseq.sml: -------------------------------------------------------------------------------- 1 | structure Graphs : GRAPHPROBLEMS = 2 | struct 3 | open Seq 4 | 5 | (* Note: complete methodology for all functions you write. *) 6 | type vertex = int 7 | type edge = vertex * vertex 8 | type graph = vertex seq seq 9 | 10 | exception not_in_graph 11 | 12 | (* Task 2.1 *) 13 | (* to_list : ’a seq -> ’a list *) 14 | (* REQUIRES: true *) 15 | (* ENSURES: to_list S converts the sequence S into a list *) 16 | fun to_list (S : 'a seq) : 'a list = 17 | case showl S of 18 | Nil => [] 19 | | Cons (x, S') => x::(to_list S') 20 | 21 | (* Task 3.1 *) 22 | (* get_neighbors : vertex seq seq -> vertex -> vertex seq *) 23 | (* REQUIRES: G is a undirected, connected graph *) 24 | (* ENSURES: get_neighbors G u evaluates to a sequence containing 25 | * only the neighbors of u in G *) 26 | fun get_neighbors (G : graph) (u : vertex) : vertex seq = 27 | if (u < length G) 28 | then (nth u G) 29 | else raise not_in_graph 30 | 31 | (* Task 3.2 *) 32 | (* from_edge : (vertex * vertex) seq -> int -> vertex seq seq *) 33 | (* REQUIRES: E is a valid list of edges for a grpah of n vertices *) 34 | (* ENSURES: from_edge E n evalutes to the adjacency list representation 35 | * of the graph with n vertices and edges E *) 36 | fun from_edge_seq (E : edge seq) (n : int) : vertex seq seq = 37 | tabulate (fn i => map (fn (x,y) => y) 38 | (filter (fn (x,y) => x = i) E)) 39 | n 40 | 41 | (* Task 3.3 *) 42 | (* is_undirected : graph -> bool *) 43 | (* REQUIRES: true *) 44 | (* ENSURES: returns true if all edges in a graph G are undirected and 45 | * false otherwise *) 46 | fun is_undirected (G : graph) : bool = 47 | let 48 | val exists = fn (x, S) => List.exists (fn y => y = x) (to_list(S)) 49 | in 50 | reduce (fn (u,v) => u andalso v) true 51 | (tabulate (fn i => mapreduce 52 | (fn x => exists (i, (nth x G))) 53 | true (fn (u,v) => u andalso v) 54 | (nth i G)) 55 | (length G)) 56 | end 57 | 58 | end 59 | 60 | structure TestGraphs = 61 | struct 62 | open Seq 63 | open Graphs 64 | 65 | fun fromList ([] : 'a list) : 'a seq = empty () 66 | | fromList (x::xs) = cons x (fromList xs) 67 | 68 | (* Tests for to_list *) 69 | val [1,2,3] = to_list(fromList([1,2,3])) 70 | val [0,5,3,1] = to_list(fromList([0,5,3,1])) 71 | val [2,2,2] = to_list(fromList([2,2,2])) 72 | val [1] = to_list(fromList([1])) 73 | 74 | (* Tests for get_neighbors *) 75 | val G = fromList([fromList([1]), fromList([0,3]), 76 | fromList([3]), fromList([1,2])]) 77 | val [1] = to_list(get_neighbors G 0) 78 | val [0,3] = to_list(get_neighbors G 1) 79 | val [3] = to_list(get_neighbors G 2) 80 | val [1,2] = to_list(get_neighbors G 3) 81 | 82 | (* Tests for from_edges *) 83 | val E = fromList([(0,1), (1,0), (1,2), (2,1)]) 84 | val [[1], [0,2], [1]] = to_list(map (fn x => to_list(x)) 85 | (from_edge_seq E 3)) 86 | 87 | (* Tests for is_undirected *) 88 | val G1 = fromList([fromList([1]), fromList([0,3]), 89 | fromList([3]), fromList([1,2])]) 90 | val G2 = fromList([fromList([1]), fromList([2]), 91 | fromList([1,3]), fromList([1,2])]) 92 | val true = is_undirected(G1) 93 | val false = is_undirected(G2) 94 | 95 | end 96 | -------------------------------------------------------------------------------- /src/ordered/utils.sml: -------------------------------------------------------------------------------- 1 | functor LEOrder (X : sig 2 | type t 3 | val le : t * t -> bool 4 | end) : ORDERED = 5 | struct 6 | type t = X.t 7 | fun compare(x,y) = 8 | case (X.le(x,y), X.le(y,x)) of 9 | (true,true) => EQUAL 10 | | (true,false) => LESS 11 | | (false,true) => GREATER 12 | | (false,false) => raise Fail "LEOrder: no relationship" 13 | end 14 | 15 | functor FlipOrder(O : ORDERED) : ORDERED = 16 | struct 17 | type t = O.t 18 | fun compare p = 19 | case O.compare p of 20 | EQUAL => EQUAL 21 | | LESS => GREATER 22 | | GREATER => LESS 23 | end 24 | 25 | (* order - * O by the O part, ignoring the first components *) 26 | functor PairSecondOrder (X : sig 27 | type left 28 | structure Right : ORDERED 29 | end) : ORDERED = 30 | struct 31 | type t = X.left * X.Right.t 32 | fun compare ((_ , x) , (_ , y)) = 33 | X.Right.compare (x,y) 34 | end 35 | 36 | functor PairOrder (A : sig 37 | structure O1 : ORDERED 38 | structure O2 : ORDERED 39 | end) : ORDERED = 40 | struct 41 | 42 | type t = A.O1.t * A.O2.t 43 | 44 | fun compare ((x,y), (x',y')) = 45 | case A.O1.compare(x,x') of 46 | LESS => LESS 47 | | GREATER => GREATER 48 | | EQUAL => A.O2.compare(y,y') 49 | 50 | end 51 | 52 | functor ListOrder (O : ORDERED) : ORDERED = 53 | struct 54 | 55 | type t = O.t list 56 | 57 | fun compare (l1, l2) = 58 | case (l1,l2) of 59 | ([],[]) => EQUAL 60 | | ([],_::_) => LESS 61 | | (_::_,[]) => GREATER 62 | | (x::xs,y::ys) => (case O.compare(x,y) of 63 | LESS => LESS 64 | | GREATER => GREATER 65 | | EQUAL => compare(xs,ys)) 66 | 67 | end 68 | 69 | signature ORDERED_UTILS = 70 | sig 71 | include ORDERED 72 | 73 | (* these return the first argument when the two are EQUAL *) 74 | val min : t * t -> t 75 | val max : t * t -> t 76 | 77 | val le : t * t -> bool 78 | val ge : t * t -> bool 79 | val lt : t * t -> bool 80 | val gt : t * t -> bool 81 | val eq : t * t -> bool 82 | end 83 | 84 | (* derive max and min for any ordered type *) 85 | functor OrderUtils (O : ORDERED) : ORDERED_UTILS = 86 | struct 87 | open O 88 | 89 | fun min (x,y) = 90 | case O.compare(x,y) 91 | of GREATER => y 92 | | _ => x 93 | 94 | fun max (x,y) = 95 | case O.compare(x,y) 96 | of LESS => y 97 | | _ => x 98 | 99 | fun le (x,y) = 100 | case O.compare(x,y) 101 | of LESS => true 102 | | EQUAL => true 103 | | GREATER => false 104 | 105 | fun lt (x,y) = 106 | case O.compare(x,y) 107 | of LESS => true 108 | | _ => false 109 | 110 | fun ge (x,y) = 111 | case O.compare(x,y) 112 | of GREATER => true 113 | | EQUAL => true 114 | | LESS => false 115 | 116 | fun gt (x,y) = 117 | case O.compare(x,y) 118 | of GREATER => true 119 | | _ => false 120 | 121 | fun eq (x,y) = 122 | case O.compare(x,y) 123 | of EQUAL => true 124 | | _ => false 125 | end 126 | -------------------------------------------------------------------------------- /hw/07/solutions/code/hw07-sol.sml: -------------------------------------------------------------------------------- 1 | 2 | (* Remove this when you're done to make sure you didn't miss anything *) 3 | exception Unimplemented 4 | 5 | datatype regexp = 6 | Zero 7 | | One 8 | | Char of char 9 | | Plus of regexp * regexp 10 | | Times of regexp * regexp 11 | | Star of regexp 12 | | Whatever 13 | | Both of regexp * regexp 14 | 15 | (* match : regexp -> char list -> (char list -> bool) -> bool *) 16 | fun match (R : regexp) (L : char list) (p : char list -> bool) : bool = 17 | case R of 18 | Zero => false 19 | | One => p L 20 | | Char c => (case L of 21 | [] => false 22 | | c' :: L' => (c = c') andalso p L') 23 | | Plus (R1, R2) => match R1 L p orelse match R2 L p 24 | | Times (R1, R2) => match R1 L (fn L' => match R2 L' p) 25 | | Star R => p L orelse match R L (fn L' => (L <> L') andalso 26 | match (Star R) L' p) 27 | (* Task 2.1 *) 28 | | Whatever => p L orelse (case L of 29 | [] => false 30 | | _ :: L' => match Whatever L' p) 31 | (* Task 2.2 *) 32 | | Both (R1, R2) => 33 | match R1 L (fn L' => match R2 L (fn L'' => L' = L'' andalso p L'')) 34 | 35 | fun accept R s = match R (String.explode s) (fn [] => true | _ => false) 36 | 37 | 38 | fun cat rs = foldr (fn (x,y) => Times (x,y)) One rs 39 | fun lit s = cat (map Char (String.explode s)) 40 | 41 | (* Task 2.1 Tests *) 42 | val rn = Char #"n" 43 | val rm = Char #"m" 44 | val true = accept Whatever "" 45 | val true = accept Whatever "The quick brown" 46 | val true = accept (Times(Whatever, Whatever)) "The quick brown" 47 | val true = accept (Times(Whatever, rn)) "The quick brown" 48 | val true = accept (Plus(Times(Whatever, rm), Times(Whatever, rn))) "The quick brown" 49 | val true = accept (Times(Char#"T", Whatever)) "The quick brown" 50 | val false = accept (Times(Char#"t", Whatever)) "The quick brown" 51 | val false = accept (Times(rn, Whatever)) "" 52 | 53 | 54 | (* Task 2.2 Tests *) 55 | val ra = Char #"a" 56 | val rb = Char #"b" 57 | val true = accept (Both(Plus(ra, rb), ra)) "a" 58 | val true = accept (Both(Star ra, Whatever)) "aaaaaa" 59 | val false = accept (Both(Times(Whatever, ra), Times(Whatever, rb))) "cccccab" 60 | val false = accept (Times(Both(ra,Times(ra,rb)),Whatever)) "abcccc" 61 | (* Tricky Case *) 62 | val tricky = Times(Both(Times(Whatever, rb), (Star ra)), Whatever) 63 | val false = accept tricky "aaabaa" 64 | 65 | (* Task 3.1 *) 66 | (* halfmatch : regexp -> regexp -> char list -> bool 67 | * REQUIRES : true 68 | * ENSURES : (halfmatch R1 R2 L ) evalutes to true iff there exist an 69 | * L1 and L2 such that 70 | L = L1 @ L2 71 | length(L1) = length (L2) 72 | L1 is in the language of R1 and L2 is in the language of R2 73 | *) 74 | fun halfmatch (R1 : regexp) (R2 : regexp) (L : char list) : bool = 75 | let 76 | val n = length L 77 | in 78 | (n mod 2 = 0) andalso 79 | match R1 L 80 | (fn L' => match R2 L' 81 | (fn L'' => null L'' andalso length L' = n div 2)) 82 | end 83 | 84 | val anbn = halfmatch (Star(Char #"0")) (Star(Char #"1")) 85 | val true = anbn (String.explode "") 86 | val true = anbn (String.explode "01") 87 | val true = anbn (String.explode "00001111") 88 | val false = anbn (String.explode "0") 89 | val false = anbn (String.explode "1") 90 | val false = anbn (String.explode "1100") 91 | val false = anbn (String.explode "001") 92 | val false = anbn (String.explode "011") 93 | val false = anbn (String.explode "11") 94 | --------------------------------------------------------------------------------