diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 000000000..864f5bf58 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,2 @@ +# Reformat remove trailing whitespaces +10ed130158ae9dc49a40951ce4a9c06a670a2d10 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 000000000..5cb0fe88c --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,344 @@ +name: Main workflow + +on: + [push] + + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Use OCaml + uses: ocaml/setup-ocaml@v2 + with: + ocaml-compiler: ocaml-variants.4.12.0+options,ocaml-option-flambda + dune-cache: true + + - name: install dependencies + run: opam exec -- dune external-lib-deps @@default | tail -n +2 | + awk '{print $2}' | grep -v "\." | xargs opam depext -iy + + - name: build solvers + run: opam exec -- make + + - name: generate patch with new binaries + run: git diff --output=binaries_patch --binary + + - name: store patch + uses: actions/upload-artifact@v2 + with: + name: binaries_patch + path: binaries_patch + retention-days: 1 + + - name: remove patch + run: rm binaries_patch + + - name: commit binaries + # This checks if the binaries in the repo are up to date and if not, + # create a new commit from the author of the last commit + run: | + git config --local user.email ${{ github.event.commits[0].author.email }} + git config --local user.name ${{ github.event.commits[0].author.name }} + git diff --quiet && git diff --staged --quiet || \ + git commit -am "${{ github.event.commits[0].message }}; update binaries" \ + --author=${{ github.event.commits[0].author.email }} + + - name: Push changes + uses: ad-m/github-push-action@master + continue-on-error: true + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + branch: ${{ github.ref }} + + - name: run ocaml tests + run: opam exec -- dune runtest + + create-virtualenv: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: '3.7' + - uses: syphar/restore-virtualenv@v1 + id: cache-virtualenv + + - uses: syphar/restore-pip-download-cache@v1 + if: steps.cache-virtualenv.outputs.cache-hit != 'true' + + - run: pip install -r requirements.txt + if: steps.cache-virtualenv.outputs.cache-hit != 'true' + + test-list: + needs: [build, create-virtualenv] + runs-on: ubuntu-latest + continue-on-error: true + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Download binaries patch + uses: actions/download-artifact@v2 + with: + name: binaries_patch + + - name: Apply binaries patch + run: | + if [ -s binaries_patch ]; then + git apply binaries_patch + fi + rm binaries_patch + + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: '3.7' + + - uses: syphar/restore-virtualenv@v1 + id: cache-virtualenv + + - name: run test + run: python bin/list.py -t 2 -RS 5 -i 2 + + test-text: + needs: [build, create-virtualenv] + runs-on: ubuntu-latest + continue-on-error: true + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Download binaries patch + uses: actions/download-artifact@v2 + with: + name: binaries_patch + + - name: Apply binaries patch + run: | + if [ -s binaries_patch ]; then + git apply binaries_patch + fi + rm binaries_patch + + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: '3.7' + + - uses: syphar/restore-virtualenv@v1 + id: cache-virtualenv + + - name: run test + run: python bin/text.py -t 2 -RS 5 -i 2 + + test-logo: + needs: [build, create-virtualenv] + runs-on: ubuntu-latest + continue-on-error: true + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Download binaries patch + uses: actions/download-artifact@v2 + with: + name: binaries_patch + + - name: Apply binaries patch + run: | + if [ -s binaries_patch ]; then + git apply binaries_patch + fi + rm binaries_patch + + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: '3.7' + + - uses: syphar/restore-virtualenv@v1 + id: cache-virtualenv + + - name: run test + continue-on-error: true + run: python bin/logo.py -t 5 -RS 10 --biasOptimal -i 2 + + test-tower: + needs: [build, create-virtualenv] + runs-on: ubuntu-latest + continue-on-error: true + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Download binaries patch + uses: actions/download-artifact@v2 + with: + name: binaries_patch + + - name: Apply binaries patch + run: | + if [ -s binaries_patch ]; then + git apply binaries_patch + fi + rm binaries_patch + + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: '3.7' + + - uses: syphar/restore-virtualenv@v1 + id: cache-virtualenv + + - name: run test + run: python bin/tower.py -t 2 -RS 5 -i 2 + + test-graph: + needs: [build, create-virtualenv] + runs-on: ubuntu-latest + continue-on-error: true + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Download binaries patch + uses: actions/download-artifact@v2 + with: + name: binaries_patch + + - name: Apply binaries patch + run: | + if [ -s binaries_patch ]; then + git apply binaries_patch + fi + rm binaries_patch + + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: '3.7' + + - uses: syphar/restore-virtualenv@v1 + id: cache-virtualenv + + - name: run test + run: | + mkdir -p tests/out + python bin/graphs.py -i 20 --checkpoints tests/resources/kellis_list_exp.pickle --export tests/out/test.png + + test-rational: + needs: [build, create-virtualenv] + runs-on: ubuntu-latest + continue-on-error: true + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Download binaries patch + uses: actions/download-artifact@v2 + with: + name: binaries_patch + + - name: Apply binaries patch + run: | + if [ -s binaries_patch ]; then + git apply binaries_patch + fi + rm binaries_patch + + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: '3.7' + + - uses: syphar/restore-virtualenv@v1 + id: cache-virtualenv + + - name: run test + run: python bin/rational.py -i 1 -t 1 --testingTimeout 1 + -RS 10 -R 10 --pseudoCounts 30 -l -1000000 --aic -1000000 -g + + test-scientificLaws: + needs: [build, create-virtualenv] + runs-on: ubuntu-latest + continue-on-error: true + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Download binaries patch + uses: actions/download-artifact@v2 + with: + name: binaries_patch + + - name: Apply binaries patch + run: | + if [ -s binaries_patch ]; then + git apply binaries_patch + fi + rm binaries_patch + + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: '3.7' + + - uses: syphar/restore-virtualenv@v1 + id: cache-virtualenv + + - name: run test + run: | + mkdir experimentOutputs + python bin/scientificLaws.py -i 1 -t 1 -RS 10 -R 10 \ + --pseudoCounts 30 -l -1000000 --aic -1000000 -g + + test-regexes: + needs: [build, create-virtualenv] + runs-on: ubuntu-latest + continue-on-error: true + if: false + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Download binaries patch + uses: actions/download-artifact@v2 + with: + name: binaries_patch + + - name: Apply binaries patch + run: | + if [ -s binaries_patch ]; then + git apply binaries_patch + fi + rm binaries_patch + + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: '3.7' + + - uses: syphar/restore-virtualenv@v1 + id: cache-virtualenv + + - name: run test + run: python bin/regexes.py -i 1 -t 1 -RS 10 -R 10 + --primitives reduced --tasks new --maxTasks 256 --ll_cutoff bigram --split 0.5 --pseudoCounts 30 + -l -1000000 --aic -1000000 --structurePenalty 1.5 --topK 2 --arity 3 --primitives strConst + --use_str_const -g diff --git a/.gitignore b/.gitignore index dcdbb4d9f..c7debe072 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ data/taskRankGraphs message sklearn-container.img .idea/ +.vscode/ venv/ ec-language-venv/ language_experiments/ diff --git a/Makefile b/Makefile index 649d0d0d7..1699f4dd2 100644 --- a/Makefile +++ b/Makefile @@ -1,26 +1,38 @@ -all: - rm -f data/geom/logoDrawString - cd solvers && \ - jbuilder build solver.exe && \ - jbuilder build versionDemo.exe && \ - jbuilder build helmholtz.exe && \ - jbuilder build logoDrawString.exe && \ - jbuilder build protonet-tester.exe && \ - jbuilder build compression.exe && \ - cp _build/default/compression.exe ../compression && \ - cp _build/default/versionDemo.exe ../versionDemo && \ - cp _build/default/solver.exe ../solver && \ - cp _build/default/helmholtz.exe ../helmholtz && \ - cp _build/default/protonet-tester.exe ../protonet-tester && \ - cp _build/default/logoDrawString.exe \ - ../logoDrawString && \ - ln -s ../../logoDrawString \ - ../data/geom/logoDrawString +all: solver compression helmholtz protonet-tester versionDemo logoDrawString + +.PHONY: solver compression helmholtz protonet-tester versionDemo logoDrawString clean: - cd solvers && jbuilder clean + dune clean rm -f solver rm -f compression rm -f helmholtz + rm -f protonet-tester + rm -f versionDemo rm -f logoDrawString rm -f data/geom/logoDrawString + +solver: + dune build solvers/solver.exe + mv solvers/solver.exe solver + +compression: + dune build solvers/compression.exe + mv solvers/compression.exe compression + +helmholtz: + dune build solvers/helmholtz.exe + mv solvers/helmholtz.exe helmholtz + +protonet-tester: + dune build solvers/protonet_tester.exe + mv solvers/protonet_tester.exe protonet-tester + +versionDemo: + dune build solvers/versionDemo.exe + mv solvers/versionDemo.exe versionDemo + +logoDrawString: + dune build solvers/logoDrawString.exe + mv solvers/logoDrawString.exe logoDrawString + ln -sf ../../logoDrawString data/geom/logoDrawString diff --git a/Readme.md b/Readme.md index baacfe6b3..201a35cff 100644 --- a/Readme.md +++ b/Readme.md @@ -14,7 +14,7 @@ 5. [PyPy](#pypy) 4. [Software Architecture](#software-architecture) 5. [`protonet-networks`](#protonet-networks) - + # Overview DreamCoder is a wake-sleep algorithm that finds programs to solve a given set of tasks in a particular domain. @@ -36,6 +36,11 @@ If you’ve already cloned the repo and did not clone the submodules, run: git submodule update --recursive --init ``` +To get better `git blame` results and skip reformatting commits run: +``` +git config blame.ignoreRevsFile .git-blame-ignore-revs +``` + ### Running using Singularity If you don't want to manually install all the of the software dependencies locally you can instead use a singularity container. To build the container, you can use the recipe `singularity` in the repository, and run the following from the root directory of the repository (tested using singularity version 2.5): @@ -197,8 +202,8 @@ make If you are not running within the singularity container, you will need to install the OCaml libraries dependencies first. Currently, in order to build the solver on a fresh opam switch, the following packages (anecdotal data from Arch x64, assuming you have `opam`) are required: ```bash opam update # Seriously, do that one -opam switch 4.06.1+flambda # caml.inria.fr/pub/docs/manual-ocaml/flambda.html -eval `opam config env` # *sight* +opam switch create 4.12.0+flambda --package=ocaml-variants.4.12.0+options,ocaml-option-flambda # caml.inria.fr/pub/docs/manual-ocaml/flambda.html +eval $(opam env) # *sight* opam install ppx_jane core re2 yojson vg cairo2 camlimages menhir ocaml-protoc zmq ``` diff --git a/compression b/compression index fc757e382..00f53f3f9 100755 Binary files a/compression and b/compression differ diff --git a/dreamcoder/enumeration.py b/dreamcoder/enumeration.py index 185a349b9..e441adbff 100644 --- a/dreamcoder/enumeration.py +++ b/dreamcoder/enumeration.py @@ -27,16 +27,16 @@ def multicoreEnumeration(g, tasks, _=None, # everything that gets sent between processes will be dilled import dill - solvers = {"ocaml": solveForTask_ocaml, - "pypy": solveForTask_pypy, - "python": solveForTask_python} - assert solver in solvers, "You must specify a valid solver. options are ocaml, pypy, or python." + solvers = {"ocaml": solveForTask_ocaml, + "pypy": solveForTask_pypy, + "python": solveForTask_python} + assert solver in solvers, "You must specify a valid solver. options are ocaml, pypy, or python." likelihoodModel = None if solver == 'pypy' or solver == 'python': # Use an all or nothing likelihood model. - likelihoodModel = AllOrNothingLikelihoodModel(timeout=evaluationTimeout) - + likelihoodModel = AllOrNothingLikelihoodModel(timeout=evaluationTimeout) + solver = solvers[solver] if not isinstance(g, dict): @@ -291,7 +291,7 @@ def taskMessage(t): message = json.dumps(message) # uncomment this if you want to save the messages being sent to the solver - + try: solver_file = os.path.join(get_root_dir(), 'solver') @@ -306,6 +306,7 @@ def taskMessage(t): except: print("response:", response) print("error:", error) + print("return code: ", process.returncode) with open("message", "w") as f: f.write(message) print("message,", message) @@ -434,7 +435,7 @@ def enumerateForTasks(g, tasks, likelihoodModel, _=None, success, likelihood = likelihoodModel.score(p, task) if not success: continue - + dt = time() - starting + elapsedTime priority = -(likelihood + prior) hits[n].push(priority, @@ -462,8 +463,3 @@ def enumerateForTasks(g, tasks, likelihoodModel, _=None, min(t for t,_ in hits[n]) for n in range(len(tasks))} return frontiers, searchTimes, totalNumberOfPrograms - - - - - diff --git a/dune-project b/dune-project new file mode 100644 index 000000000..b594f4dba --- /dev/null +++ b/dune-project @@ -0,0 +1,4 @@ +(lang dune 2.9) + +(name dreamcoder) +(using menhir 2.1) diff --git a/helmholtz b/helmholtz index 9b6a40eb9..94c870081 100755 Binary files a/helmholtz and b/helmholtz differ diff --git a/logoDrawString b/logoDrawString index 524f23fe0..90355d626 100755 Binary files a/logoDrawString and b/logoDrawString differ diff --git a/protonet-tester b/protonet-tester index 40630a669..1e4745ada 100755 Binary files a/protonet-tester and b/protonet-tester differ diff --git a/singularity b/singularity index e01f1b4f1..d867ac019 100644 --- a/singularity +++ b/singularity @@ -30,7 +30,7 @@ From: ubuntu chmod 777 /container HOME=/container export HOME - + wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh chmod +x Miniconda3-latest-Linux-x86_64.sh ./Miniconda3-latest-Linux-x86_64.sh -b -p /usr/local/conda @@ -39,14 +39,14 @@ From: ubuntu conda install -y numpy dill pyzmq matplotlib protobuf scikit-learn scipy pip install dill sexpdata pygame pycairo cairocffi psutil pypng Box2D-kengz graphviz frozendict pathos - + conda install pytorch torchvision -c pytorch - + opam init -y --auto-setup --root /container/.opam opam update - opam switch create 4.06.1+flambda + opam switch create 4.12.0+flambda --package=ocaml-variants.4.12.0+options,ocaml-option-flambda eval `opam config env` - opam install -y ppx_jane core re2 yojson vg cairo2 camlimages menhir ocaml-protoc zmq utop jbuilder + opam install -y ppx_jane core re2 yojson vg cairo2 camlimages menhir ocaml-protoc zmq utop dune #opam install ocp-indent merlin echo " #use "topfind";; @@ -55,7 +55,7 @@ From: ubuntu #require "core.syntax";; open Core;; " >> /container/.ocamlinit - echo 'eval `opam config env`' >> /container/.bashrc + echo 'eval `opam config env`' >> /container/.bashrc @@ -69,6 +69,3 @@ open Core;; pypy3 -m pip install vmprof pypy3 -m pip install dill pypy3 -m pip install psutil - - - \ No newline at end of file diff --git a/solver b/solver index 4b75472de..81b998d8c 100755 Binary files a/solver and b/solver differ diff --git a/solvers/CachingTable.ml b/solvers/CachingTable.ml index d2739bbe3..c2dbf22c7 100644 --- a/solvers/CachingTable.ml +++ b/solvers/CachingTable.ml @@ -24,7 +24,7 @@ module CachingTable = struct let refresh m n = match m.newest_key with - | Some(newest) when newest == n -> () + | Some(newest) when phys_equal newest n -> () | _ -> (* Remove n from doubly linked list *) @@ -32,7 +32,7 @@ module CachingTable = struct | None -> (match m.oldest_key with | Some(n') -> - assert (n == n'); + assert (phys_equal n n'); m.oldest_key <- n.next | None -> assert (false)) | Some(p) -> p.next <- n.next); @@ -41,10 +41,10 @@ module CachingTable = struct | Some(successor) -> successor.previous <- n.previous); (match m.oldest_key with - | Some(o) when o == n -> assert (false) + | Some(o) when phys_equal o n -> assert (false) | None | Some(_) -> ()); (match m.newest_key with - | Some(newest) when newest == n -> assert (false) + | Some(newest) when phys_equal newest n -> assert (false) | None | Some(_) -> ()); (* insert at the front of list *) @@ -96,7 +96,9 @@ module CachingTable = struct (match m.oldest_key with | None -> m.oldest_key <- Some(entry) | Some(_) -> ()); - assert (Hashtbl.add m.mapping ~key:k ~data:(v, entry) = `Ok); + assert (match Hashtbl.add m.mapping ~key:k ~data:(v, entry) with + | `Ok -> true + | _ -> false); collect m | Some((_,entry)) -> @@ -110,13 +112,13 @@ module CachingTable = struct (match successor.previous with | None -> assert (false) | Some(this) -> - assert (this == e); + assert (phys_equal this e); forward successor) | None -> match m.newest_key with | None -> assert (false) | Some(this) -> - assert (this.node_key == e.node_key) + assert (phys_equal this.node_key e.node_key) in @@ -126,19 +128,19 @@ module CachingTable = struct (match predecessor.next with | None -> assert (false) | Some(this) -> - assert (this == e); + assert (phys_equal this e); backward predecessor) | None -> match m.oldest_key with - | Some(this) -> assert (this == e) + | Some(this) -> assert (phys_equal this e) | None -> assert (false) in (match m.newest_key, m.oldest_key with | None, None -> () | Some(newest), Some(oldest) -> - (assert (oldest.previous = None); - assert (newest.next = None); + (assert (Option.is_none oldest.previous); + assert (Option.is_none newest.next); forward oldest; backward newest) | None, Some(_) -> assert (false) @@ -153,13 +155,13 @@ module CachingTable = struct entries |> List.iter ~f:(fun entry -> match Hashtbl.find m.mapping entry.node_key with | None -> assert (false) - | Some(_,entry') -> assert (entry == entry')); + | Some(_,entry') -> assert (phys_equal entry entry')); Hashtbl.iteri m.mapping ~f:(fun ~key ~data:(_,entry) -> assert (1 = (entries |> List.filter ~f:(fun entry' -> - if entry' == entry then - (assert (entry'.node_key == key); + if phys_equal entry' entry then + (assert (phys_equal entry'.node_key key); true) else false) |> List.length))) @@ -181,16 +183,16 @@ module CachingTable = struct | Some(v') -> assert (v = v'); assert (v = Hashtbl.find_exn ground_truth k); check_consistency m in - for i = 1 to 100 do + for _ = 1 to 100 do step(); historical m |> List.iter ~f:(Printf.eprintf "%d "); Printf.eprintf "\n"; backward_historical m |> List.rev |> List.iter ~f:(Printf.eprintf "%d "); Printf.eprintf "\n" - done - + done + end;; - + (* CachingTable.test() *) diff --git a/solvers/Dreaming.ml b/solvers/Dreaming.ml index 902a2a2d3..98e60163e 100644 --- a/solvers/Dreaming.ml +++ b/solvers/Dreaming.ml @@ -3,16 +3,12 @@ open Core open Pregex open Program open Enumeration -open Grammar open Utils open Timeout open Type open Tower open PolyValue -open Yojson.Basic - - let remove_bad_dreams behavior_to_programs : (PolyList.t * (float * program list)) list = let start_time = Time.now () in @@ -28,15 +24,15 @@ let remove_bad_dreams behavior_to_programs : (PolyList.t * (float * program list (* number of inputs *) let l = ref None in - Hashtbl.iteri behavior_to_programs ~f:(fun ~key ~data -> + Hashtbl.iteri behavior_to_programs ~f:(fun ~key ~data:_ -> match !l with | None -> l := Some(List.length key) | Some(l') -> assert (List.length key = l')); let l = !l |> get_some in - + let containers = Array.init l ~f:(fun _ -> make_poly_table()) in let output_vectors = empty_resizable() in - + Hashtbl.iteri behavior_to_programs ~f:(fun ~key ~data -> let this_index = output_vectors.ra_occupancy in push_resizable output_vectors (key, data); @@ -44,7 +40,7 @@ let remove_bad_dreams behavior_to_programs : (PolyList.t * (float * program list let outputs = key in outputs |> List.iteri ~f:(fun output_index this_output -> (* Record that we are one of the behaviors that produces this output *) - if this_output = PolyValue.None then () else + if PolyValue.equal this_output PolyValue.None then () else match Hashtbl.find containers.(output_index) this_output with | None -> Hashtbl.set containers.(output_index) ~key:this_output ~data:(Int.Set.singleton this_index) @@ -54,11 +50,11 @@ let remove_bad_dreams behavior_to_programs : (PolyList.t * (float * program list (* Checks whether there exists another output vector that contains everything in this vector *) let is_bad_index i = - let dominating = ref None in + let dominating = ref None in let outputs, _ = get_resizable output_vectors i in (* Initialize dominating to be the smallest set *) outputs |> List.iteri ~f:(fun output_index this_output -> - if this_output = PolyValue.None then () else + if PolyValue.equal this_output PolyValue.None then () else match Hashtbl.find containers.(output_index) this_output with | None -> assert (false) | Some(others) -> @@ -67,7 +63,7 @@ let remove_bad_dreams behavior_to_programs : (PolyList.t * (float * program list | _ -> ()); outputs |> List.iteri ~f:(fun output_index this_output -> - if this_output = PolyValue.None then () else + if PolyValue.equal this_output PolyValue.None then () else match Hashtbl.find containers.(output_index) this_output with | None -> assert (false) | Some(others) -> @@ -75,7 +71,7 @@ let remove_bad_dreams behavior_to_programs : (PolyList.t * (float * program list | None -> dominating := Some(others) | Some(d) -> dominating := Some(Int.Set.inter d others)); let nightmare = Int.Set.length (!dominating |> get_some) > 1 in - if nightmare && false then begin + if nightmare && false then begin Printf.eprintf "NIGHTMARE!!!"; get_resizable output_vectors i |> snd |> snd |> List.iter ~f:(fun p -> p |> string_of_program |> Printf.eprintf "%s\n") (* get_resizable output_vectors i |> fst |> List.iter2_exn extra ~f:(fun i pv -> *) @@ -85,17 +81,17 @@ let remove_bad_dreams behavior_to_programs : (PolyList.t * (float * program list in let number_of_nightmares = ref 0 in - let sweet_dreams = + let sweet_dreams = List.range 0 output_vectors.ra_occupancy |> List.filter_map ~f:(fun i -> if is_bad_index i then (incr number_of_nightmares; None) else - Some(get_resizable output_vectors i)) + Some(get_resizable output_vectors i)) in Printf.eprintf "Removed %d nightmares in %s.\n" (!number_of_nightmares) (Time.diff (Time.now ()) start_time |> Time.Span.to_string); sweet_dreams - + let helmholtz_enumeration (behavior_hash : program -> (PolyList.t*float) option) ?nc:(nc=1) g request ~timeout ~maximumSize = assert (nc = 1); (* FIXME *) @@ -104,6 +100,7 @@ let helmholtz_enumeration (behavior_hash : program -> (PolyList.t*float) option) let update ~key ~data = let l,extra_cost,ps = data in + let open Float in match Hashtbl.find behavior_to_programs key with (* never seen this behavior before *) | None -> Hashtbl.set behavior_to_programs ~key ~data:data @@ -116,7 +113,7 @@ let helmholtz_enumeration (behavior_hash : program -> (PolyList.t*float) option) when extra_cost > extra_cost' || (extra_cost = extra_cost' && l' < l) -> () (* we are the same cost but less likely *) - | Some((l',extra_cost',ps')) + | Some((l',extra_cost',_ps')) when extra_cost = extra_cost' && l < l' -> () (* we cannot be a different cost or of the other conditions would've fired *) @@ -136,13 +133,13 @@ let helmholtz_enumeration (behavior_hash : program -> (PolyList.t*float) option) (* unused *) let merge other = Hashtbl.iteri other ~f:update - in + in set_enumeration_timeout timeout; let rec loop lb = - if enumeration_timed_out() then () else begin - let final_results = + if enumeration_timed_out() then () else begin + let final_results = enumerate_programs ~extraQuiet:true ~nc:nc ~final:(fun () -> [behavior_to_programs]) g request lb (lb+.1.5) (fun p l -> if Hashtbl.length behavior_to_programs > maximumSize then set_enumeration_timeout (-1.0) else @@ -162,7 +159,7 @@ let helmholtz_enumeration (behavior_hash : program -> (PolyList.t*float) option) let rec unpack x = let open Yojson.Basic.Util in - + try magical (x |> to_int) with _ -> try magical (x |> to_number) with _ -> try magical (x |> to_bool) with _ -> @@ -174,8 +171,7 @@ let rec unpack x = x |> to_list |> List.map ~f:unpack |> magical with _ -> raise (Failure "could not unpack") -let rec pack t v : json = - let open Yojson.Basic.Util in +let rec pack t v : Yojson.Basic.t = match t with | TCon("list",[t'],_) -> `List(magical v |> List.map ~f:(pack t')) | TCon("int",[],_) -> `Int(magical v) @@ -184,12 +180,10 @@ let rec pack t v : json = | _ -> assert false let special_helmholtz = Hashtbl.Poly.create();; -let register_special_helmholtz name handle = Hashtbl.set special_helmholtz name handle;; +let register_special_helmholtz name handle = Hashtbl.set special_helmholtz ~key:name ~data:handle;; let default_hash ?timeout:(timeout=0.001) request inputs : program -> (PolyList.t*float) option = - let open Yojson.Basic.Util in - (* convert json -> ocaml *) let inputs : 'a list list = unpack inputs in let return = return_of_type request in @@ -201,7 +195,7 @@ let default_hash ?timeout:(timeout=0.001) request inputs : program -> (PolyList. match run_for_interval ~attempts:2 timeout (fun () -> run_lazy_analyzed_with_arguments p input) with - | Some(value) -> PolyValue.pack return value + | Some(value) -> PolyValue.pack return value | _ -> PolyValue.None with (* We have to be a bit careful with exceptions if the * synthesized program generated an exception, then we just @@ -216,21 +210,19 @@ let default_hash ?timeout:(timeout=0.001) request inputs : program -> (PolyList. else None let string_hash ?timeout:(timeout=0.001) request inputs : program -> (PolyList.t*float) option = - let open Yojson.Basic.Util in - (* convert json -> ocaml *) let inputs : 'a list list = unpack inputs in let return = return_of_type request in let testConstants=["x4";"a bc d"] in - let constants = testConstants |> List.map ~f:String.to_list in + let constants = testConstants |> List.map ~f:String.to_list in fun program -> let constant_results = (* results from substituting with each constant *) constants |> List.concat_map ~f:(fun constant -> match substitute_string_constants [constant] program with - | [program'] -> - let p = analyze_lazy_evaluation program' in + | [program'] -> + let p = analyze_lazy_evaluation program' in inputs |> List.map ~f:(fun input -> try match run_for_interval ~attempts:2 @@ -248,7 +240,8 @@ let string_hash ?timeout:(timeout=0.001) request inputs : program -> (PolyList.t else None ;; -register_special_helmholtz "string" string_hash;; +let _ : unit = + register_special_helmholtz "string" string_hash;; @@ -297,14 +290,11 @@ register_special_helmholtz "string" string_hash;; (* with *) (* | None -> None *) (* | *) - - -let tower_hash ?timeout:(timeout=0.001) request inputs : program -> (PolyList.t*float) option = - let open Yojson.Basic.Util in - assert (request = (ttower @> ttower)); - +let tower_hash ?timeout:(timeout=0.001) request _inputs : program -> (PolyList.t*float) option = + assert (equal_tp request (ttower @> ttower)); + fun program -> let arrangement = evaluate_discrete_tower_program timeout program in let l = List.length arrangement in @@ -318,15 +308,17 @@ let tower_hash ?timeout:(timeout=0.001) request inputs : program -> (PolyList.t* PolyValue.Integer(d);]))) in Some([j],0.) ;; -register_special_helmholtz "tower" tower_hash;; + +let _ : unit = + register_special_helmholtz "tower" tower_hash;; let logo_hash ?timeout:(timeout=0.001) request inputs : program -> (PolyList.t*float) option = let open Yojson.Basic.Util in - assert (request = (turtle @> turtle)); + assert (equal_tp request (turtle @> turtle)); (* disgusting hack *) let costMatters = 1 = (inputs |> to_list |> List.hd_exn |> to_list |> List.hd_exn |> to_int) in - + let table = Hashtbl.Poly.create() in fun program -> @@ -334,7 +326,7 @@ let logo_hash ?timeout:(timeout=0.001) request inputs : program -> (PolyList.t*f let l = run_for_interval ~attempts:2 timeout (fun () -> let x = run_lazy_analyzed_with_arguments p [] in let l = LogoLib.LogoInterpreter.turtle_to_list x in - if not (LogoLib.LogoInterpreter.logo_contained_in_canvas l) then None else + if not (LogoLib.LogoInterpreter.logo_contained_in_canvas l) then None else match Hashtbl.find table l with | Some(a) -> Some(a) | None -> begin @@ -350,11 +342,11 @@ let logo_hash ?timeout:(timeout=0.001) request inputs : program -> (PolyList.t*f let j = PolyValue.List(range (28*28) |> List.map ~f:(fun i -> PolyValue.Integer(a.{i}))) in let cost = if costMatters then cost else 0. in Some([j],cost);; -register_special_helmholtz "LOGO" logo_hash;; +let _ : unit = + register_special_helmholtz "LOGO" logo_hash;; -let regex_hash ?timeout:(timeout=0.001) request inputs : program -> (PolyList.t*float) option = - let open Yojson.Basic.Util in - assert (request = (tregex @> tregex)); +let regex_hash ?timeout:(timeout=0.001) request _inputs : program -> (PolyList.t*float) option = + assert (equal_tp request (tregex @> tregex)); let rec poly_of_regex = function | Constant(s) -> PolyValue.List ([PolyValue.Integer(0); @@ -375,11 +367,12 @@ let regex_hash ?timeout:(timeout=0.001) request inputs : program -> (PolyList.t in let default_constant = build_constant_regex ['c';'o';'n';'s';'t';'9';'#';] in fun expression -> - if number_of_free_parameters expression > 1 then None else + if number_of_free_parameters expression > 1 then None else run_for_interval ~attempts:2 timeout - (fun () -> + (fun () -> let r = expression |> substitute_constant_regex default_constant |> regex_of_program |> canonical_regex in ([poly_of_regex r],0.)) ;; -register_special_helmholtz "regex" regex_hash;; +let _ : unit = + register_special_helmholtz "regex" regex_hash;; diff --git a/solvers/EC.ml b/solvers/EC.ml index 96d23573f..698dd4ecb 100644 --- a/solvers/EC.ml +++ b/solvers/EC.ml @@ -43,7 +43,7 @@ let rec exploration_compression (* fragments |> List.iter ~f:(fun f -> Printf.printf "FRAGMENT\t%s\n" (string_of_fragment f)); *) Out_channel.flush stdout; - + let gf = time_it "Induced grammar" @@ fun _ -> induce_fragment_grammar ~lambda:lambda ~alpha:alpha ~beta:beta fragments frontiers (fragment_grammar_of_grammar g) in @@ -57,4 +57,3 @@ let rec exploration_compression Out_channel.flush stdout; exploration_compression tasks gp frontier_size ~keepTheBest:keepTheBest (iterations - 1) - diff --git a/solvers/Euclid.ml b/solvers/Euclid.ml index 5afec369e..045ea4e00 100644 --- a/solvers/Euclid.ml +++ b/solvers/Euclid.ml @@ -30,5 +30,5 @@ let eqTriangle = TwoD(Line(Id1(P(P(P(P(P(P(C))))))),Id1(P(P(C))))) ; TwoD(Line(Id1(P(P(P(P(P(P(C))))))),Id1(P(P(P(C)))))) ] -let _ = (* Do nothing. I'm interested in the typing so far. *) +let _ : unit = (* Do nothing. I'm interested in the typing so far. *) print_endline "Success, I was typed." diff --git a/solvers/FastType.ml b/solvers/FastType.ml index bbb0d929e..27e31d1ed 100644 --- a/solvers/FastType.ml +++ b/solvers/FastType.ml @@ -52,13 +52,13 @@ let compile_unifier t = (* todo because f is known ahead of time we can compile this into closures *) let rec fu f t k : tContext = match (f,t) with - | (FastVariable(r), t) -> begin + | (FastVariable(r), t) -> begin match !r with | None -> r := Some(t); k | Some(t') -> unify k t t' end | (FastConstructor(n,fs,_),TCon(n',ss,_)) -> - if n = n' then + if String.(=) n n' then List.fold2_exn ~init:k ~f:(fun k f s -> fu f s k) fs ss else raise UnificationFailure | (FastConstructor(_,_,Some(t')),TID(j)) -> @@ -99,15 +99,15 @@ let compile_unifier t = Array.iter mapping ~f:(fun r -> r := None); (context, arguments) - + let test_fast() = let library_types = [t1 @> t0 @> tlist t0 @> tlist t0] in let requesting_types = [tlist tint; tlist t1; t2] in - library_types |> List.iter ~f:(fun library_type -> + library_types |> List.iter ~f:(fun library_type -> let u = compile_unifier library_type in - requesting_types |> List.iter ~f:(fun request -> + requesting_types |> List.iter ~f:(fun request -> let k = makeTIDs (next_type_variable request) empty_context in let (k,arguments) = u k request in diff --git a/solvers/Helmholtz.ml b/solvers/Helmholtz.ml index 3cd44ed06..5045ab769 100644 --- a/solvers/Helmholtz.ml +++ b/solvers/Helmholtz.ml @@ -2,19 +2,14 @@ open Core open Dreaming -open Pregex open Program -open Enumeration open Grammar -open Utils -open Timeout open Type -open Tower - + open Yojson.Basic - - + + let run_job channel = let open Yojson.Basic.Util in @@ -53,21 +48,20 @@ let run_job channel = helmholtz_enumeration ~nc:nc (k ~timeout:evaluationTimeout request (j |> member "extras")) g request ~timeout ~maximumSize let output_job ?maxExamples:(maxExamples=50000) result = - let open Yojson.Basic.Util in (* let result = Hashtbl.to_alist result in *) let results = let l = List.length result in if l < maxExamples then result else let p = (maxExamples |> Float.of_int)/.(l |> Float.of_int) in - result |> List.filter ~f:(fun _ -> Random.float 1. < p) + result |> List.filter ~f:(fun _ -> Float.(<) (Random.float 1.) p) in - let message : json = - `List(results |> List.map ~f:(fun (behavior, (l,ps)) -> + let message : Yojson.Basic.t = + `List(results |> List.map ~f:(fun (_behavior, (l,ps)) -> `Assoc([(* "behavior", behavior; *) "ll", `Float(l); "programs", `List(ps |> List.map ~f:(fun p -> `String(p |> string_of_program)))]))) - in + in message -let _ = - run_job Pervasives.stdin |> remove_bad_dreams |> output_job |> to_channel Pervasives.stdout +let _ : unit = + run_job Stdlib.stdin |> remove_bad_dreams |> output_job |> to_channel Stdlib.stdout diff --git a/solvers/PolyValue.ml b/solvers/PolyValue.ml index bfb637209..0aee98574 100644 --- a/solvers/PolyValue.ml +++ b/solvers/PolyValue.ml @@ -3,8 +3,7 @@ open Core open Utils open Type -open Yojson.Basic - + module PolyValue = struct type t = | List of t list @@ -13,7 +12,7 @@ module PolyValue = struct | Boolean of bool | Character of char | None - [@@deriving compare, hash, sexp_of] + [@@deriving compare, hash, sexp_of, equal] let rec pack t v : t = match t with @@ -35,12 +34,12 @@ module PolyValue = struct | Character(c) -> Printf.sprintf "'%c'" c | None -> "None" - let rec of_json (j : Yojson.Basic.json) : t = match j with + let rec of_json (j : Yojson.Basic.t) : t = match j with | `List(l) -> List(l |> List.map ~f:of_json) | `Int(i) -> Integer(i) | `Bool(b) -> Boolean(b) | _ -> assert (false) - + end;; let make_poly_table() = Hashtbl.create (module PolyValue) diff --git a/solvers/TikZ.ml b/solvers/TikZ.ml index f00e09f5a..b31a9937f 100644 --- a/solvers/TikZ.ml +++ b/solvers/TikZ.ml @@ -3,12 +3,10 @@ open Core open Utils open Type open Program -open Enumeration -open Task -open Grammar open Task type vector = Vector of int*int +[@@deriving equal, compare] let string_of_vector = function | Vector(x,y) -> "(" ^ string_of_int x ^ "," ^ string_of_int y ^ ")" @@ -16,15 +14,16 @@ type command = | Circle of vector | Rectangle of vector*vector | Line of vector*vector +[@@deriving equal, compare] let canonical_command_list : 'a Core.List.t -> 'a Core.List.t = fun l -> let l2 = List.dedup_and_sort - ~compare:(fun c1 c2 -> if c1 > c2 then 1 else if c1 = c2 then 0 else -1) + ~compare:compare_command l in List.sort - ~compare:(fun c1 c2 -> if c1 > c2 then 1 else if c1 = c2 then 0 else -1) + ~compare:compare_command l2 type cid = C|R|L @@ -61,7 +60,7 @@ let primitive_loop = primitive "loop" let body = (0--(n-1)) |> List.map ~f:body |> List.concat in let boundary = match boundary with | None -> [] - | Some(b) -> (0--(n-2)) |> List.map ~f:b |> List.concat + | Some(b) -> (0--(n-2)) |> List.map ~f:b |> List.concat in boundary@body);; let primitive_union = primitive "trace-union" (ttrace @> ttrace @> ttrace) (@);; @@ -101,7 +100,7 @@ let make_empty_guess () = {rectangles = g(); circles = g(); lines = g();} - + let score_latex output = (* Calculate all of the different possible coefficients/intercepts/coordinates/etc. *) @@ -115,7 +114,7 @@ let score_latex output = g.circles.y_slope <- (y1 - y2) :: g.circles.y_slope; g.circles.y_slope <- (y2 - y1) :: g.circles.y_slope; end - | (Rectangle(Vector(x1,y1),Vector(x2,y2)),Rectangle(Vector(a1,b1),Vector(a2,b2))) -> begin + | (Rectangle(Vector(x1,y1),Vector(x2,y2)),Rectangle(Vector(a1,b1),Vector(a2,b2))) -> begin g.rectangles.x_slope <- (x1 - a1) :: g.rectangles.x_slope; g.rectangles.x_slope <- (a1 - x1) :: g.rectangles.x_slope; g.rectangles.x_slope <- (x2 - a2) :: g.rectangles.x_slope; @@ -124,7 +123,7 @@ let score_latex output = g.rectangles.y_slope <- (y1 - b1) :: g.rectangles.y_slope; g.rectangles.y_slope <- (b1 - y1) :: g.rectangles.y_slope; g.rectangles.y_slope <- (y2 - b2) :: g.rectangles.y_slope; - g.rectangles.y_slope <- (b2 - y2) :: g.rectangles.y_slope; + g.rectangles.y_slope <- (b2 - y2) :: g.rectangles.y_slope; end | _ -> () and single_guesses = function @@ -155,7 +154,7 @@ let score_latex output = g.circles.x_slope |> List.iter ~f:(Printf.eprintf "cxm: %d\t"); g.circles.y_slope |> List.iter ~f:(Printf.eprintf "cym: %d\t"); Printf.eprintf "\n\n"; - + let rec random_instantiation ~x ~i expression = match expression with | Primitive(t,"COORDINATE",_) -> Primitive(t,"COORDINATE",magical @@ ref (random_choice @@ match i with @@ -199,26 +198,26 @@ let score_latex output = let output = canonical_command_list output in - fun program -> begin + fun program -> begin if List.exists (0--100) ~f:(fun _ -> let p = random_instantiation ~x:false ~i:C program in let v : command list = evaluate [] p |> magical |> canonical_command_list in - v = output) + equal_list equal_command v output) then begin Printf.eprintf "PROGRAM: %s\n" (string_of_program program); 10.*. likelihood_penalty program end else log 0. - end - - - + end + + + let latex_task name output = {name = name; task_type = ttrace; log_likelihood = score_latex output} - - + + (* let () = *) (* let p = parse_program "(loop 3 nothing (lambda (circle (linear COEFFICIENT INTERCEPT $0 COEFFICIENT INTERCEPT $0))))" |> get_some in *) (* Printf.printf "%s\n" (string_of_program p); *) diff --git a/solvers/cache_pb.ml b/solvers/cache_pb.ml index 0620986a9..72dca1026 100644 --- a/solvers/cache_pb.ml +++ b/solvers/cache_pb.ml @@ -54,17 +54,17 @@ let rec decode_tower_cash_block d = | Some (1, Pbrt.Varint) -> begin v.x10 <- Pbrt.Decoder.int32_as_varint d; x10_is_set := true; end - | Some (1, pk) -> + | Some (1, pk) -> Pbrt.Decoder.unexpected_payload "Message(tower_cash_block), field(1)" pk | Some (2, Pbrt.Varint) -> begin v.w10 <- Pbrt.Decoder.int32_as_varint d; w10_is_set := true; end - | Some (2, pk) -> + | Some (2, pk) -> Pbrt.Decoder.unexpected_payload "Message(tower_cash_block), field(2)" pk | Some (3, Pbrt.Varint) -> begin v.h10 <- Pbrt.Decoder.int32_as_varint d; h10_is_set := true; end - | Some (3, pk) -> + | Some (3, pk) -> Pbrt.Decoder.unexpected_payload "Message(tower_cash_block), field(3)" pk | Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind done; @@ -94,37 +94,37 @@ let rec decode_tower_cash_entry d = | Some (4, Pbrt.Bytes) -> begin v.plan <- (decode_tower_cash_block (Pbrt.Decoder.nested d)) :: v.plan; end - | Some (4, pk) -> + | Some (4, pk) -> Pbrt.Decoder.unexpected_payload "Message(tower_cash_entry), field(4)" pk | Some (5, Pbrt.Bits32) -> begin v.height <- Pbrt.Decoder.float_as_bits32 d; height_is_set := true; end - | Some (5, pk) -> + | Some (5, pk) -> Pbrt.Decoder.unexpected_payload "Message(tower_cash_entry), field(5)" pk | Some (6, Pbrt.Bits32) -> begin v.stability <- Pbrt.Decoder.float_as_bits32 d; stability_is_set := true; end - | Some (6, pk) -> + | Some (6, pk) -> Pbrt.Decoder.unexpected_payload "Message(tower_cash_entry), field(6)" pk | Some (7, Pbrt.Bits32) -> begin v.area <- Pbrt.Decoder.float_as_bits32 d; area_is_set := true; end - | Some (7, pk) -> + | Some (7, pk) -> Pbrt.Decoder.unexpected_payload "Message(tower_cash_entry), field(7)" pk | Some (8, Pbrt.Bits32) -> begin v.length <- Pbrt.Decoder.float_as_bits32 d; length_is_set := true; end - | Some (8, pk) -> + | Some (8, pk) -> Pbrt.Decoder.unexpected_payload "Message(tower_cash_entry), field(8)" pk | Some (9, Pbrt.Bits32) -> begin v.overpass <- Pbrt.Decoder.float_as_bits32 d; overpass_is_set := true; end - | Some (9, pk) -> + | Some (9, pk) -> Pbrt.Decoder.unexpected_payload "Message(tower_cash_entry), field(9)" pk | Some (10, Pbrt.Bits32) -> begin v.staircase <- Pbrt.Decoder.float_as_bits32 d; staircase_is_set := true; end - | Some (10, pk) -> + | Some (10, pk) -> Pbrt.Decoder.unexpected_payload "Message(tower_cash_entry), field(10)" pk | Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind done; @@ -155,7 +155,7 @@ let rec decode_tower_cash d = | Some (1, Pbrt.Bytes) -> begin v.entries <- (decode_tower_cash_entry (Pbrt.Decoder.nested d)) :: v.entries; end - | Some (1, pk) -> + | Some (1, pk) -> Pbrt.Decoder.unexpected_payload "Message(tower_cash), field(1)" pk | Some (_, payload_kind) -> Pbrt.Decoder.skip d payload_kind done; @@ -163,37 +163,37 @@ let rec decode_tower_cash d = Cache_types.entries = v.entries; } : Cache_types.tower_cash) -let rec encode_tower_cash_block (v:Cache_types.tower_cash_block) encoder = - Pbrt.Encoder.key (1, Pbrt.Varint) encoder; +let rec encode_tower_cash_block (v:Cache_types.tower_cash_block) encoder = + Pbrt.Encoder.key (1, Pbrt.Varint) encoder; Pbrt.Encoder.int32_as_varint v.Cache_types.x10 encoder; - Pbrt.Encoder.key (2, Pbrt.Varint) encoder; + Pbrt.Encoder.key (2, Pbrt.Varint) encoder; Pbrt.Encoder.int32_as_varint v.Cache_types.w10 encoder; - Pbrt.Encoder.key (3, Pbrt.Varint) encoder; + Pbrt.Encoder.key (3, Pbrt.Varint) encoder; Pbrt.Encoder.int32_as_varint v.Cache_types.h10 encoder; () -let rec encode_tower_cash_entry (v:Cache_types.tower_cash_entry) encoder = - List.iter (fun x -> - Pbrt.Encoder.key (4, Pbrt.Bytes) encoder; +let rec encode_tower_cash_entry (v:Cache_types.tower_cash_entry) encoder = + List.iter (fun x -> + Pbrt.Encoder.key (4, Pbrt.Bytes) encoder; Pbrt.Encoder.nested (encode_tower_cash_block x) encoder; ) v.Cache_types.plan; - Pbrt.Encoder.key (5, Pbrt.Bits32) encoder; + Pbrt.Encoder.key (5, Pbrt.Bits32) encoder; Pbrt.Encoder.float_as_bits32 v.Cache_types.height encoder; - Pbrt.Encoder.key (6, Pbrt.Bits32) encoder; + Pbrt.Encoder.key (6, Pbrt.Bits32) encoder; Pbrt.Encoder.float_as_bits32 v.Cache_types.stability encoder; - Pbrt.Encoder.key (7, Pbrt.Bits32) encoder; + Pbrt.Encoder.key (7, Pbrt.Bits32) encoder; Pbrt.Encoder.float_as_bits32 v.Cache_types.area encoder; - Pbrt.Encoder.key (8, Pbrt.Bits32) encoder; + Pbrt.Encoder.key (8, Pbrt.Bits32) encoder; Pbrt.Encoder.float_as_bits32 v.Cache_types.length encoder; - Pbrt.Encoder.key (9, Pbrt.Bits32) encoder; + Pbrt.Encoder.key (9, Pbrt.Bits32) encoder; Pbrt.Encoder.float_as_bits32 v.Cache_types.overpass encoder; - Pbrt.Encoder.key (10, Pbrt.Bits32) encoder; + Pbrt.Encoder.key (10, Pbrt.Bits32) encoder; Pbrt.Encoder.float_as_bits32 v.Cache_types.staircase encoder; () -let rec encode_tower_cash (v:Cache_types.tower_cash) encoder = - List.iter (fun x -> - Pbrt.Encoder.key (1, Pbrt.Bytes) encoder; +let rec encode_tower_cash (v:Cache_types.tower_cash) encoder = + List.iter (fun x -> + Pbrt.Encoder.key (1, Pbrt.Bytes) encoder; Pbrt.Encoder.nested (encode_tower_cash_entry x) encoder; ) v.Cache_types.entries; () diff --git a/solvers/cache_types.ml b/solvers/cache_types.ml index 212f756f5..33499ba11 100644 --- a/solvers/cache_types.ml +++ b/solvers/cache_types.ml @@ -21,7 +21,7 @@ type tower_cash = { entries : tower_cash_entry list; } [@@unboxed] -let rec default_tower_cash_block +let rec default_tower_cash_block ?x10:((x10:int32) = 0l) ?w10:((w10:int32) = 0l) ?h10:((h10:int32) = 0l) @@ -31,7 +31,7 @@ let rec default_tower_cash_block h10; } -let rec default_tower_cash_entry +let rec default_tower_cash_entry ?plan:((plan:tower_cash_block list) = []) ?height:((height:float) = 0.) ?stability:((stability:float) = 0.) @@ -49,7 +49,7 @@ let rec default_tower_cash_entry staircase; } -let rec default_tower_cash +let rec default_tower_cash ?entries:((entries:tower_cash_entry list) = []) () : tower_cash = { entries; diff --git a/solvers/cache_types.mli b/solvers/cache_types.mli index 1bdac6164..f2201c9e1 100644 --- a/solvers/cache_types.mli +++ b/solvers/cache_types.mli @@ -27,7 +27,7 @@ type tower_cash = { (** {2 Default values} *) -val default_tower_cash_block : +val default_tower_cash_block : ?x10:int32 -> ?w10:int32 -> ?h10:int32 -> @@ -35,7 +35,7 @@ val default_tower_cash_block : tower_cash_block (** [default_tower_cash_block ()] is the default value for type [tower_cash_block] *) -val default_tower_cash_entry : +val default_tower_cash_entry : ?plan:tower_cash_block list -> ?height:float -> ?stability:float -> @@ -47,7 +47,7 @@ val default_tower_cash_entry : tower_cash_entry (** [default_tower_cash_entry ()] is the default value for type [tower_cash_entry] *) -val default_tower_cash : +val default_tower_cash : ?entries:tower_cash_entry list -> unit -> tower_cash diff --git a/solvers/client.ml b/solvers/client.ml index 527a3ca16..951bc6758 100644 --- a/solvers/client.ml +++ b/solvers/client.ml @@ -1,12 +1,11 @@ open Core -open Zmq type socket_connection = (([`Req] Zmq.Socket.t) ref * int) ;; let context = ref (Zmq.Context.create());; let socket_connections : (socket_connection list) ref = ref [];; -let socket_json (socket : socket_connection) message = +let socket_json (socket : socket_connection) message = let open Yojson.Safe in let message = to_string message in let socket,_ = socket in @@ -14,7 +13,7 @@ let socket_json (socket : socket_connection) message = let response = Zmq.Socket.recv !socket in response |> from_string -let connect_socket' p : [`Req] Zmq.Socket.t = +let connect_socket' p : [`Req] Zmq.Socket.t = let socket = Zmq.Socket.create !context Zmq.Socket.req in Zmq.Socket.connect socket @@ "tcp://localhost:"^(p |> Int.to_string); socket @@ -36,7 +35,7 @@ let refresh_socket_connections() = end let close_socket_connections() = - !socket_connections |> List.iter ~f:(fun (r,p) -> + !socket_connections |> List.iter ~f:(fun (r,_) -> Zmq.Socket.close !r); socket_connections := [] diff --git a/solvers/combinator.ml b/solvers/combinator.ml index 9240eb6ef..b062313a2 100644 --- a/solvers/combinator.ml +++ b/solvers/combinator.ml @@ -39,8 +39,8 @@ let rec program_to_combinator = function program_to_combinator (Abstraction(x))) | _ -> raise (Failure "program to combinator") -let combinator_to_program p = - let rec combinator_to_program_ = function +let combinator_to_program p = + let rec combinator_to_program_ = function | Primitive(_,"I") -> Abstraction(Index(0)) | Primitive(_,"K") -> Abstraction(Abstraction(Index(1))) | Primitive(_,"S") -> Abstraction(Abstraction(Abstraction(Apply(Apply(Index(2),Index(0)), @@ -83,7 +83,7 @@ let combinator_to_program p = | Some(p) -> repeatedly_reduce p in combinator_to_program_ p |> repeatedly_reduce - + let test_combinator() = [cS;cI;cB;cC;cK;] |> List.iter ~f:(fun (Primitive(t,n)) -> @@ -107,4 +107,5 @@ let test_combinator() = ;; -test_combinator();; +let _ : unit = + test_combinator();; diff --git a/solvers/compression.ml b/solvers/compression.ml index d35da3e8a..df9c7db18 100644 --- a/solvers/compression.ml +++ b/solvers/compression.ml @@ -1,16 +1,12 @@ open Core - -open Gc - -open Physics -open Pregex -open Tower +open [@warning "-33"] Physics +open [@warning "-33"] Pregex +open [@warning "-33"] Tower open Utils open Type open Program open Enumeration -open Task open Grammar (* open Eg *) @@ -25,7 +21,7 @@ let restrict ~topK g frontier = let restriction = frontier.programs |> List.map ~f:(fun (p,ll) -> (ll+.likelihood_under_grammar g frontier.request p,p,ll)) |> - sort_by (fun (posterior,_,_) -> 0.-.posterior) |> + sort_by (fun (posterior,_,_) -> 0. -. posterior) |> List.map ~f:(fun (_,p,ll) -> (p,ll)) in {request=frontier.request; programs=List.take restriction topK} @@ -65,14 +61,14 @@ let inside_outside ~pseudoCounts g (frontiers : frontier list) = (g, summaries |> List.map ~f:(fun ss -> ss |> List.map ~f:(fun (l,s) -> l+. summary_likelihood g s) |> lse_list) |> fold1 (+.)) - - + + let grammar_induction_score ~aic ~structurePenalty ~pseudoCounts frontiers g = let g,ll = inside_outside ~pseudoCounts g frontiers in let production_size = function | Primitive(_,_,_) -> 1 - | Invented(_,e) -> begin + | Invented(_,e) -> begin (* Ignore illusory fix1/abstraction, it does not contribute to searching cost *) let e = recursively_get_abstraction_body e in match e with @@ -80,14 +76,14 @@ let grammar_induction_score ~aic ~structurePenalty ~pseudoCounts frontiers g = | _ -> program_size e end | _ -> raise (Failure "Element of grammar is neither primitive nor invented") - in + in (g, ll-. aic*.(List.length g.library |> Float.of_int) -. structurePenalty*.(g.library |> List.map ~f:(fun (p,_,_,_) -> production_size p) |> sum |> Float.of_int)) - + exception EtaExpandFailure;; @@ -96,7 +92,7 @@ let eta_long request e = let make_long e request = if is_arrow request then Some(Abstraction(Apply(shift_free_variables 1 e, Index(0)))) else None - in + in let rec visit request environment e = match e with | Abstraction(b) when is_arrow request -> @@ -131,7 +127,7 @@ let eta_long request e = in let e' = visit request [] e in - + assert (tp_eq (e |> closed_inference |> canonical_type) (e' |> closed_inference |> canonical_type)); @@ -150,11 +146,11 @@ let normalize_invention i = visit d x) | Primitive(_,_,_) | Invented(_,_) as e -> e in - + let renamed = visit 0 i in let abstracted = List.fold_right mapping ~init:renamed ~f:(fun _ e -> Abstraction(e)) in make_invention abstracted - + let rewrite_with_invention i = (* Raises EtaExpandFailure if this is not successful *) @@ -181,7 +177,7 @@ let rewrite_with_invention i = (beta_normal_form ~reduceInventions:true e')); e' with UnificationFailure -> begin - if !verbose_compression then begin + if !verbose_compression then begin Printf.eprintf "WARNING: rewriting with invention gave ill typed term.\n"; Printf.eprintf "Original:\t\t%s\n" (e |> string_of_program); Printf.eprintf "Original:\t\t%s\n" (e |> beta_normal_form ~reduceInventions:true |> string_of_program); @@ -192,10 +188,10 @@ let rewrite_with_invention i = end; let normal_original = e |> beta_normal_form ~reduceInventions:true in let normal_rewritten = e |> visit |> beta_normal_form ~reduceInventions:true in - assert (program_equal normal_original normal_rewritten); + assert (program_equal normal_original normal_rewritten); raise EtaExpandFailure end - + let nontrivial e = let indices = ref [] in @@ -215,7 +211,6 @@ let nontrivial e = !primitives > 1 || !primitives = 1 && !duplicated_indices > 0 ;; -open Zmq type worker_command = | Rewrite of program list @@ -223,7 +218,7 @@ type worker_command = | KillWorker | FinalFrontier of program | BatchedRewrite of program list - + let compression_worker connection ~inline ~arity ~bs ~topK g frontiers = let context = Zmq.Context.create() in let socket = Zmq.Socket.create context Zmq.Socket.req in @@ -270,7 +265,7 @@ let compression_worker connection ~inline ~arity ~bs ~topK g frontiers = let v, frontier_indices = garbage_collect_versions ~verbose:!verbose_compression v frontier_indices in Gc.compact(); - + let cost_table = empty_cost_table v in (* pack the candidates into a version space for efficiency *) @@ -280,10 +275,10 @@ let compression_worker connection ~inline ~arity ~bs ~topK g frontiers = let reachable : int list list = frontier_indices |> List.map ~f:(reachable_versions v) in let inhabitants : int list list = reachable |> List.map ~f:(fun indices -> List.concat_map ~f:(snd % minimum_cost_inhabitants cost_table) indices |> - List.dedup_and_sort ~compare:(-) |> + List.dedup_and_sort ~compare:(-) |> List.map ~f:(List.hd_exn % extract v) |> List.filter ~f:nontrivial |> - List.map ~f:(incorporate candidate_table)) in + List.map ~f:(incorporate candidate_table)) in inhabitants) in if !verbose_compression then Printf.eprintf "(worker) Total candidates: [%s] = %d, packs into %d vs\n" @@ -294,10 +289,10 @@ let compression_worker connection ~inline ~arity ~bs ~topK g frontiers = (* relay this information to the master, whose job it is to pool the candidates *) send (candidates,candidate_table.i2s); - let candidate_table = () in + let [@warning "-26"] candidate_table = () in let candidates : program list = receive() in let candidates : int list = candidates |> List.map ~f:(incorporate v) in - + if !verbose_compression then (Printf.eprintf "(worker) Got %d candidates.\n" (List.length candidates); flush_everything()); @@ -309,13 +304,13 @@ let compression_worker connection ~inline ~arity ~bs ~topK g frontiers = send candidate_scores; (* I hope that this leads to garbage collection *) - let candidate_scores = () - and cost_table = () + let [@warning "-26"] candidate_scores = () + and [@warning "-26"] cost_table = () in Gc.compact(); let rewrite_frontiers invention_source = - time_it ~verbose:!verbose_compression "(worker) rewrote frontiers" (fun () -> + time_it ~verbose:!verbose_compression "(worker) rewrote frontiers" (fun () -> time_it ~verbose:!verbose_compression "(worker) gc during rewrite" Gc.compact; let intersectionTable = Some(Hashtbl.Poly.create()) in let i = incorporate v invention_source in @@ -329,13 +324,13 @@ let compression_worker connection ~inline ~arity ~bs ~topK g frontiers = let index = incorporate v originalProgram |> n_step_inversion ~inline v ~n:arity in let program = minimal_inhabitant ~intersectionTable new_cost_table ~given:(Some(i)) index |> get_some - in + in let program' = try rewriter frontier.request program with EtaExpandFailure -> originalProgram in (program',ll)) - in + in {request=frontier.request; programs=programs'}) in @@ -371,7 +366,7 @@ let compression_worker connection ~inline ~arity ~bs ~topK g frontiers = with EtaExpandFailure -> originalProgram in (program',ll)) - in + in {request=frontier.request; programs=programs'}))) in @@ -384,34 +379,34 @@ let compression_worker connection ~inline ~arity ~bs ~topK g frontiers = frontiers := original_frontiers; let v = new_version_table() in let frontier_inversions = Hashtbl.Poly.create() in - time_it ~verbose:!verbose_compression "(worker) did final inversion" (fun () -> + time_it ~verbose:!verbose_compression "(worker) did final inversion" (fun () -> !frontiers |> List.iter ~f:(fun f -> f.programs |> List.iter ~f:(fun (p,_) -> Hashtbl.set frontier_inversions ~key:(incorporate v p) ~data:(n_step_inversion ~inline v ~n:arity (incorporate v p))))); - clear_dynamic_programming_tables v; Gc.compact(); - + clear_dynamic_programming_tables v; Gc.compact(); + let i = incorporate v invention in let new_cost_table = empty_cheap_cost_table v in - time_it ~verbose:!verbose_compression "(worker) did final refactor" (fun () -> + time_it ~verbose:!verbose_compression "(worker) did final refactor" (fun () -> List.map !frontiers ~f:(fun frontier -> let programs' = List.map frontier.programs ~f:(fun (originalProgram, ll) -> - let index = Hashtbl.find_exn frontier_inversions (incorporate v originalProgram) in + let index = Hashtbl.find_exn frontier_inversions (incorporate v originalProgram) in let program = minimal_inhabitant new_cost_table ~given:(Some(i)) index |> get_some - in + in let program' = try rewrite_with_invention invention frontier.request program with EtaExpandFailure -> originalProgram in (program',ll)) - in + in {request=frontier.request; programs=programs'})) - in + in while true do match receive() with @@ -424,7 +419,7 @@ let compression_worker connection ~inline ~arity ~bs ~topK g frontiers = (frontiers := original_frontiers; send (final_rewrite invention); Gc.compact()) - | KillWorker -> + | KillWorker -> (Zmq.Socket.close socket; Zmq.Context.terminate context; exit 0) @@ -444,7 +439,7 @@ let compression_step_master ~inline ~nc ~structurePenalty ~aic ~pseudoCounts ?ar | _ -> () in - if !verbose_compression then ignore(Unix.system "ps aux|grep compression 1>&2"); + if !verbose_compression then ignore(Unix.system "ps aux|grep compression 1>&2" : Core.Unix.Exit_or_signal.t); let divide_work_fairly nc xs = let nt = List.length xs in @@ -481,28 +476,28 @@ let compression_step_master ~inline ~nc ~structurePenalty ~aic ~pseudoCounts ?ar send KillWorker; sockets |> List.iter ~f:(fun s -> Zmq.Socket.close s); Zmq.Context.terminate context - in - - - + in + + + let candidates : program list list = sockets |> List.map ~f:(fun s -> let candidate_message : (int list list)*(vs ra) = receive s in let (candidates, candidate_table) = candidate_message in let candidate_table = {(new_version_table()) with i2s=candidate_table} in - candidates |> List.map ~f:(List.map ~f:(singleton_head % extract candidate_table))) |> List.concat in + candidates |> List.map ~f:(List.map ~f:(singleton_head % extract candidate_table))) |> List.concat in let candidates : program list = occurs_multiple_times (List.concat candidates) in Printf.eprintf "Total number of candidates: %d\n" (List.length candidates); Printf.eprintf "Constructed version spaces and coalesced candidates in %s.\n" (Time.diff (Time.now ()) start_time |> Time.Span.to_string); flush_everything(); - + send candidates; let candidate_scores : float list list = sockets |> List.map ~f:(fun s -> let ss : float list = receive s in ss) in if !verbose_compression then (Printf.eprintf "(master) Received worker beams\n"; flush_everything()); - let candidates : program list = + let candidates : program list = candidate_scores |> List.transpose_exn |> List.map ~f:(fold1 (+.)) |> List.zip_exn candidates |> List.sort ~compare:(fun (_,s1) (_,s2) -> Float.compare s1 s2) |> List.map ~f:fst @@ -520,7 +515,7 @@ let compression_step_master ~inline ~nc ~structurePenalty ~aic ~pseudoCounts ?ar match candidates with | [] -> (finish(); None) - | _ -> + | _ -> (* now we have our final list of candidates! *) (* ask each of the workers to rewrite w/ each candidate *) @@ -531,7 +526,7 @@ let compression_step_master ~inline ~nc ~structurePenalty ~aic ~pseudoCounts ?ar sockets |> List.map ~f:receive |> List.transpose_exn |> List.map ~f:List.concat) in assert (List.length new_frontiers = List.length candidates); - + let score frontiers candidate = let new_grammar = uniform_grammar (normalize_invention candidate :: grammar_primitives g) in let g',s = grammar_induction_score ~aic ~pseudoCounts ~structurePenalty frontiers new_grammar in @@ -544,8 +539,8 @@ let compression_step_master ~inline ~nc ~structurePenalty ~aic ~pseudoCounts ?ar frontiers |> List.iter ~f:(fun f -> Printf.eprintf "%s\n" (string_of_frontier f)); Printf.eprintf "\n"; flush_everything()); (g',s) - in - + in + let _,initial_score = grammar_induction_score ~aic ~structurePenalty ~pseudoCounts (frontiers |> List.map ~f:(restrict ~topK g)) g in @@ -555,7 +550,7 @@ let compression_step_master ~inline ~nc ~structurePenalty ~aic ~pseudoCounts ?ar List.map2_exn candidates new_frontiers ~f:(fun candidate frontiers -> (score frontiers candidate, candidate)) |> minimum_by (fun ((_,s),_) -> -.s)) in - if best_score < initial_score then + if Float.(<) best_score initial_score then (Printf.eprintf "No improvement possible.\n"; finish(); None) else (let new_primitive = grammar_primitives g' |> List.hd_exn in @@ -572,14 +567,14 @@ let compression_step_master ~inline ~nc ~structurePenalty ~aic ~pseudoCounts ?ar let g'' = inside_outside ~pseudoCounts g' frontiers'' |> fst in Some(g'',frontiers'')) - - - - - - - + + + + + + + let compression_step ~inline ~structurePenalty ~aic ~pseudoCounts ?arity:(arity=3) ~bs ~topI ~topK g frontiers = let restrict frontier = @@ -594,11 +589,11 @@ let compression_step ~inline ~structurePenalty ~aic ~pseudoCounts ?arity:(arity= let original_frontiers = frontiers in let frontiers = ref (List.map ~f:restrict frontiers) in - + let score g frontiers = grammar_induction_score ~aic ~pseudoCounts ~structurePenalty frontiers g in - + let v = new_version_table() in let cost_table = empty_cost_table v in @@ -606,7 +601,7 @@ let compression_step ~inline ~structurePenalty ~aic ~pseudoCounts ?arity:(arity= let frontier_indices : int list list = time_it "calculated version spaces" (fun () -> !frontiers |> List.map ~f:(fun f -> f.programs |> List.map ~f:(fun (p,_) -> incorporate v p |> n_step_inversion ~inline v ~n:arity))) in - + let candidates : int list = time_it "proposed candidates" (fun () -> let reachable : int list list = frontier_indices |> List.map ~f:(reachable_versions v) in @@ -617,14 +612,14 @@ let compression_step ~inline ~structurePenalty ~aic ~pseudoCounts ?arity:(arity= in let candidates = candidates |> List.filter ~f:(fun candidate -> let candidate = List.hd_exn (extract v candidate) in - try (ignore(normalize_invention candidate); nontrivial candidate) + try (ignore(normalize_invention candidate : program); nontrivial candidate) with UnificationFailure -> false) - in + in Printf.eprintf "Got %d candidates.\n" (List.length candidates); match candidates with | [] -> None - | _ -> + | _ -> let ranked_candidates = time_it "beamed version spaces" (fun () -> beam_costs ~ct:cost_table ~bs candidates frontier_indices) @@ -639,7 +634,7 @@ let compression_step ~inline ~structurePenalty ~aic ~pseudoCounts ?arity:(arity= if List.mem ~equal:program_equal (grammar_primitives g) new_primitive then raise DuplicatePrimitive; let new_grammar = uniform_grammar (new_primitive :: (grammar_primitives g)) - in + in let rewriter = rewrite_with_invention invention_source in (* Extract the frontiers in terms of the new primitive *) @@ -649,13 +644,13 @@ let compression_step ~inline ~structurePenalty ~aic ~pseudoCounts ?arity:(arity= let programs' = List.map frontier.programs ~f:(fun (originalProgram, ll) -> let index = incorporate v originalProgram |> n_step_inversion v ~inline ~n:arity in - let program = minimal_inhabitant new_cost_table ~given:(Some(i)) index |> get_some in + let program = minimal_inhabitant new_cost_table ~given:(Some(i)) index |> get_some in let program' = try rewriter frontier.request program with EtaExpandFailure -> originalProgram in (program',ll)) - in + in {request=frontier.request; programs=programs'}) in @@ -668,9 +663,8 @@ let compression_step ~inline ~structurePenalty ~aic ~pseudoCounts ?arity:(arity= let _,initial_score = score g !frontiers in Printf.eprintf "Initial score: %f\n" initial_score; - - let best_score,g',frontiers',best_index = - time_it (Printf.sprintf "Evaluated top-%d candidates" topI) (fun () -> + let best_score,g',_frontiers',best_index = + time_it (Printf.sprintf "Evaluated top-%d candidates" topI) (fun () -> ranked_candidates |> List.map ~f:(fun (c,i) -> let source = extract v i |> singleton_head in let source = normalize_invention source in @@ -683,13 +677,13 @@ let compression_step ~inline ~structurePenalty ~aic ~pseudoCounts ?arity:(arity= c s; frontiers' |> List.iter ~f:(fun f -> let f = string_of_frontier f in - if String.is_substring ~substring:(string_of_program source) f then + if String.is_substring ~substring:(string_of_program source) f then Printf.eprintf "%s\n" f); Printf.eprintf "\n"; flush_everything()); (s,g',frontiers',i)) |> minimum_by (fun (s,_,_,_) -> -.s)) in - if best_score < initial_score then + if Float.(<) best_score initial_score then (Printf.eprintf "No improvement possible.\n"; None) else (let new_primitive = grammar_primitives g' |> List.hd_exn in @@ -710,10 +704,9 @@ let export_compression_checkpoint ~nc ~structurePenalty ~aic ~topK ~pseudoCounts let timestamp = Time.now() |> Time.to_filename_string ~zone:Time.Zone.utc in let fn = Printf.sprintf "compressionMessages/%s" timestamp in - let open Yojson.Basic.Util in let open Yojson.Basic in - let j : json = + let j : Yojson.Basic.t = `Assoc(["DSL", serialize_grammar g; "topK", `Int(topK); "topI", `Int(topI); @@ -740,7 +733,7 @@ let compression_loop singleton_head in let illustrate_new_primitive new_grammar primitive frontiers = - let illustrations = + let illustrations = frontiers |> List.filter_map ~f:(fun frontier -> let best_program = (restrict ~topK:1 new_grammar frontier).programs |> List.hd_exn |> fst in if List.mem ~equal:program_equal (program_subexpressions best_program) primitive then @@ -751,14 +744,14 @@ let compression_loop (List.length illustrations); Printf.eprintf "Here is where it is used:\n"; illustrations |> List.iter ~f:(fun program -> Printf.eprintf " %s\n" (string_of_program program)) - in + in - let step = if nc = 1 then compression_step else compression_step_master ~nc in + let step = if nc = 1 then compression_step else compression_step_master ~nc in let rec loop ~iterations g frontiers = if iterations < 1 then (Printf.eprintf "Exiting ocaml compression because of iteration bound.\n";g, frontiers) - else + else match time_it "Completed one step of memory consolidation" (fun () -> step ~inline ~structurePenalty ~topK ~aic ~pseudoCounts ~arity ~bs ~topI g frontiers) with @@ -768,29 +761,22 @@ let compression_loop if !verbose_compression && iterations > 1 then export_compression_checkpoint ~nc ~structurePenalty ~aic ~topK ~pseudoCounts ~arity ~bs ~topI g' frontiers'; flush_everything(); - loop (iterations - 1) g' frontiers' + loop ~iterations:(iterations - 1) g' frontiers' in time_it "completed ocaml compression" (fun () -> loop ~iterations g frontiers) ;; - - - - - - - let () = let open Yojson.Basic.Util in let open Yojson.Basic in let j = - if Array.length Sys.argv > 1 then - (assert (Array.length Sys.argv = 2); - Yojson.Basic.from_file Sys.argv.(1)) - else - Yojson.Basic.from_channel Pervasives.stdin + if Array.length (Sys.get_argv ()) > 1 then + (assert (Array.length (Sys.get_argv ()) = 2); + Yojson.Basic.from_file (Sys.get_argv ()).(1)) + else + Yojson.Basic.from_channel Stdlib.stdin in let g = j |> member "DSL" |> deserialize_grammar |> strip_grammar in let topK = j |> member "topK" |> to_int in @@ -815,11 +801,11 @@ let () = with _ -> false) ; if !collect_data then verbose_compression := true; - + let inline = (try j |> member "inline" |> to_bool with _ -> true) - in + in let nc = try j |> member "CPUs" |> to_int @@ -835,13 +821,13 @@ let () = flush_everything(); let frontiers = j |> member "frontiers" |> to_list |> List.map ~f:deserialize_frontier in - + let g, frontiers = - if aic > 500. then + if Float.(>) aic 500. then (Printf.eprintf "AIC is very large (over 500), assuming you don't actually want to do DSL learning!"; g, frontiers) - else compression_loop ~inline ~iterations ~nc ~topK ~aic ~structurePenalty ~pseudoCounts ~arity ~topI ~bs g frontiers in - + else compression_loop ~inline ~iterations ~nc ~topK ~aic ~structurePenalty ~pseudoCounts ~arity ~topI ~bs g frontiers in + let j = `Assoc(["DSL",serialize_grammar g; "frontiers",`List(frontiers |> List.map ~f:serialize_frontier)]) diff --git a/solvers/differentiation.ml b/solvers/differentiation.ml index 7268c8fee..bb086c905 100644 --- a/solvers/differentiation.ml +++ b/solvers/differentiation.ml @@ -3,7 +3,7 @@ open Core open Type open Program open Utils - + type variable = {mutable gradient : float option; mutable data : float option; volatile : bool; (* whether this depends on something which is a function of learned parameters *) @@ -44,10 +44,10 @@ let make_binary_variable forward backward a b = let make_unitary_variable forward backward a = make_variable (fun x -> match x with - |[a;] -> forward a + |[a;] -> forward a |_ -> raise (Failure "unitary variable did not get 1 arguments")) (fun x -> match x with - |[a;] -> backward a + |[a;] -> backward a |_ -> raise (Failure "urinary variable did not get 1 backward arguments")) [a;] @@ -85,15 +85,15 @@ let random_variable ?mean:(mean = 0.) ?standard_deviation:(standard_deviation = in s let update_variable v x = - assert (v.arguments = []); + assert (List.is_empty v.arguments); v.data <- Some(x) let (+&) = - make_binary_variable (+.) (fun _ _ -> [1.;1.]) + make_binary_variable (+.) (fun _ _ -> [1.;1.]) let (-&) = - make_binary_variable (-.) (fun _ _ -> [1.;-1.]) + make_binary_variable (-.) (fun _ _ -> [1.;-1.]) let ( *& ) = make_binary_variable ( *. ) (fun a b -> [b;a]) @@ -118,21 +118,22 @@ let square_root = make_unitary_variable sqrt (fun a -> [0.5/.(sqrt a)]) let clamp ~l ~u = + let open Float in make_unitary_variable (fun a -> if a > u then u else if a < l then l else a) (fun a -> if a > u || a < l then [0.] else [1.]) - + let log_soft_max xs = - make_variable (fun vs -> - let m : float = List.fold_right vs ~init:Float.neg_infinity ~f:max in + make_variable (fun vs -> + let m : float = List.fold_right vs ~init:Float.neg_infinity ~f:Float.max in let zm = List.fold_right ~init:0. ~f:(fun x a -> exp (x -. m) +. a) vs in m+. (log zm)) - (fun vs -> - let m : float = List.fold_right vs ~init:Float.neg_infinity ~f:max in + (fun vs -> + let m : float = List.fold_right vs ~init:Float.neg_infinity ~f:Float.max in let zm = List.fold_right ~init:0. ~f:(fun x a -> exp (x -. m) +. a) vs in List.map vs ~f:(fun x -> (exp (x-.m)) /. zm)) xs @@ -153,7 +154,7 @@ let rec zero_gradients z = List.iter z.arguments ~f:(fun a -> zero_gradients a); z.gradient <- None; z.descendents <- []; - if z.arguments = [] then () else z.data <- None + if List.is_empty z.arguments then () else z.data <- None end let rec forward z = @@ -171,7 +172,7 @@ let rec forward z = let backward z = z.gradient <- Some(1.0); let rec b v = - ignore(differentiate v); + ignore(differentiate v : float); List.iter ~f:b v.arguments in b z @@ -186,13 +187,13 @@ let rec run_optimizer opt ?update:(update = 1000) let l = update_network loss in if iterations = 0 then l else begin - if update > 0 && iterations mod update = 0 then begin + if update > 0 && iterations mod update = 0 then begin Printf.eprintf "LOSS: %f\n" l; parameters |> List.iter ~f:(fun p -> Printf.eprintf "parameter %f\t" (p.data |> get_some)); Printf.eprintf "\n"; end else (); - parameters |> List.map ~f:differentiate |> opt |> + parameters |> List.map ~f:differentiate |> opt |> List.iter2_exn parameters ~f:(fun x dx -> let v = x.data |> get_some in update_variable x (v +. dx)); @@ -206,17 +207,18 @@ let restarting_optimize opt ?update:(update = 1000) parameters |> List.iter ~f:(fun parameter -> update_variable parameter (uniform_interval ~l:(-5.) ~u:5.)); run_optimizer opt ~update:update ~iterations:iterations parameters loss) |> - fold1 min + fold1 Float.min let gradient_descent ?lr:(lr = 0.001) = List.map ~f:(fun dx -> ~-. (lr*.dx)) -let rprop ?lr:(lr=0.1) ?decay:(decay=0.5) ?grow:(grow=1.2) = +let rprop ?lr:(lr=0.1) ?decay:(decay=0.5) ?grow:(grow=1.2) = let first_iteration = ref true in let previous_signs = ref [] in let individual_rates = ref [] in fun dxs -> + let open Float in let new_signs = dxs |> List.map ~f:(fun dx -> dx > 0.) in if !first_iteration then begin first_iteration := false; @@ -226,14 +228,14 @@ let rprop ?lr:(lr=0.1) ?decay:(decay=0.5) ?grow:(grow=1.2) = previous_signs := new_signs; individual_rates := dxs |> List.map ~f:(fun _ -> lr); - updates - end else begin + updates + end else begin individual_rates := List.map3_exn !individual_rates !previous_signs new_signs ~f:(fun individual_rate previous_sign new_sign -> - if previous_sign = new_sign + if Bool.(=) previous_sign new_sign then individual_rate*.grow else individual_rate*.decay); - + let updates = List.map2_exn !individual_rates dxs ~f:(fun individual_rate dx -> if dx > 0. @@ -249,7 +251,7 @@ let proportional_optimize parameters loss_pairs = parameters |> List.iter ~f:(fun p -> update_variable p 1.); let prediction_variables = loss_pairs |> List.map ~f:fst in prediction_variables |> List.iter ~f:zero_gradients; - let predictions = prediction_variables |> List.map ~f:forward in + (* let predictions = prediction_variables |> List.map ~f:forward in *) assert (false) (* TODO *) let test_differentiation () = @@ -262,21 +264,21 @@ let test_differentiation () = update_variable x 2.; update_variable y 10.; - ignore(update_network z); + ignore(update_network z : float); - Printf.printf "dL/dx = %f\tdL/dy = %f\n" (differentiate x) (differentiate y); + Printf.printf "dL/dx = %f\tdL/dy = %f\n" (differentiate x) (differentiate y); update_variable x 2.; update_variable y 2.; - ignore(update_network z); + ignore(update_network z : float); Printf.printf "z = %f\n" (z.data |> get_some); Printf.printf "dL/dx = %f\tdL/dy = %f\n" (differentiate x) (differentiate y); let l = ((~$ 0.) -& z) in - ignore(run_optimizer (gradient_descent ~lr:0.001) [x;y] l) + ignore(run_optimizer (gradient_descent ~lr:0.001) [x;y] l : float) ;; @@ -340,7 +342,7 @@ let rec polymorphic_loss_pairs : tp -> 'a -> 'b -> (variable*variable) list = fu | t -> raise (Failure ("placeholder_data: bad type "^(string_of_type t))) -let rec polymorphic_sse ?clipOutput:(clipOutput=None) ?clipLoss:(clipLoss=None) t = +let polymorphic_sse ?clipOutput:(clipOutput=None) ?clipLoss:(clipLoss=None) t = let get_pairs = polymorphic_loss_pairs t in fun p y -> let loss_pairs = get_pairs p y in @@ -372,12 +374,12 @@ let rec polymorphic_sse ?clipOutput:(clipOutput=None) ?clipLoss:(clipLoss=None) (* List.fold2_exn p y ~init:(~$0.) ~f:(fun a _p _y -> a +& (e _p _y)) *) (* with _ -> raise DifferentiableBadShape) *) (* | t -> raise (Failure ("placeholder_data: bad type "^(string_of_type t))) *) - + let test_program_differentiation() = let p = parse_program "(lambda REAL)" |> get_some in - let (p, parameters) = replace_placeholders p in + let (p, _parameters) = replace_placeholders p in let p = analyze_lazy_evaluation p in let g = run_lazy_analyzed_with_arguments p [~$ 0.] in @@ -416,7 +418,7 @@ let test_program_differentiation() = (* | Summation(ss) -> ss |> List.map ~f:show_symbolic |> join ~separator:" + " |> Printf.sprintf "(%s)" *) (* | Product(ss) -> ss |> List.map ~f:show_symbolic |> join ~separator:" * " |> Printf.sprintf "(%s)" *) (* | Quotient(n,d) -> Printf.sprintf "(%s / %s)" (show_symbolic n) (show_symbolic d) *) - + (* let program_to_symbolic_expression p = *) @@ -467,7 +469,7 @@ let test_program_differentiation() = (* let q = q @ (List.range (List.length q) d |> List.map ~f:(fun _ -> SymbolicZero)) in *) (* List.map2_exn p q ~f:make_summation *) (* in *) - + (* let rec multiply_polynomials p q = *) (* match p with *) (* | [] -> [] *) @@ -476,7 +478,7 @@ let test_program_differentiation() = (* (q |> List.map ~f:(fun q' -> make_product k q')) *) (* (multiply_polynomials p q |> multiply_polynomial_by_x) *) (* in *) - + (* let rec simplify_product (components : canonical_polynomial list) = *) (* match components with *) (* | [] -> assert (false) *) @@ -484,7 +486,7 @@ let test_program_differentiation() = (* | x :: y :: z -> *) (* multiply_polynomials x y :: z |> simplify_product *) (* in *) - + (* match s with *) (* | SymbolicVariable -> [SymbolicZero;SymbolicUnit;], [SymbolicUnit] *) (* | SymbolicConstant(_) -> [s], [SymbolicUnit] *) @@ -528,7 +530,7 @@ let test_program_differentiation() = (* | Product(ss) -> *) (* let ss = ss |> List.map ~f:simplify_coefficient in *) (* assert (false) *) - + (* (n |> List.map ~f:simplify_coefficient, *) (* d |> List.map ~f:simplify_coefficient) *) @@ -546,7 +548,3 @@ let test_program_differentiation() = (* ;; *) (* test_simplify() *) - - - - diff --git a/solvers/dune b/solvers/dune new file mode 100644 index 000000000..f2af468bd --- /dev/null +++ b/solvers/dune @@ -0,0 +1,11 @@ +(executables + (names solver compression helmholtz geomDrawLambdaString geomDrawFile + geomTest logoTest logoDrawString logoSequenceString protonet_tester client + versionDemo) + (modes native) + (ocamlopt_flags :standard -O3 -unboxed-types -nodynlink -w -20) + (libraries core re2 yojson geomLib logoLib ocaml-protoc zmq core_kernel.pairing_heap) ;parmap + (preprocess + (pps ppx_jane)) + (promote (until-clean)) +) diff --git a/solvers/enumeration.ml b/solvers/enumeration.ml index 253635996..72db68e9f 100644 --- a/solvers/enumeration.ml +++ b/solvers/enumeration.ml @@ -1,4 +1,5 @@ open Core +module Heap = Pairing_heap open Parallel @@ -28,8 +29,7 @@ let deserialize_frontier j = {programs;request} let serialize_frontier f = - let open Yojson.Basic in - let j : json = + let j : Yojson.Basic.t = `Assoc(["request",serialize_type f.request; "programs",`List(f.programs |> List.map ~f:(fun (p,l) -> `Assoc(["program",`String(string_of_program p); @@ -37,10 +37,10 @@ let serialize_frontier f = in j -let violates_symmetry f a n = +let violates_symmetry f a n = if not (is_base_primitive f) then false else let a = application_function a in - if not (is_base_primitive a) then false else + if not (is_base_primitive a) then false else match (n, primitive_name f, primitive_name a) with (* McCarthy primitives *) | (0,"car","cons") -> true @@ -95,7 +95,7 @@ let path_environment p = | A(t) -> Some(t) | _ -> None) |> List.rev -let string_of_state {skeleton;context;path;cost} = +let string_of_state {skeleton;context;path;cost;_} = let string_of_turn = function | L -> "L" | R -> "R" @@ -105,10 +105,10 @@ let string_of_state {skeleton;context;path;cost} = cost (string_of_program skeleton) (path |> List.map ~f:string_of_turn |> join ~separator:" ") (path |> path_environment |> List.map ~f:string_of_type |> join ~separator:",") -let state_finished {path;skeleton;} = +let state_finished {path;skeleton;_} = match skeleton with | Primitive(_,"??",_) -> false - | _ -> path = [] + | _ -> List.is_empty path let initial_best_first_state request (g : grammar) = {skeleton = primitive_unknown request g; @@ -123,7 +123,7 @@ let rec follow_path e path = | (Apply(_,x), R :: p') -> follow_path x p' | (Abstraction(body),(A(_)) :: p') -> follow_path body p' - | (Primitive(t,"??",_), []) -> e + | (Primitive(_,"??",_), []) -> e | _ -> assert false let rec modify_skeleton e q path = @@ -132,7 +132,7 @@ let rec modify_skeleton e q path = | (Apply(f,x), R :: p') -> Apply(f, modify_skeleton x q p') | (Abstraction(body),(A(_)) :: p') -> Abstraction(modify_skeleton body q p') - | (Primitive(t,"??",_), []) -> q + | (Primitive(_,"??",_), []) -> q | _ -> assert false let unwind_path p = @@ -141,10 +141,10 @@ let unwind_path p = | (A(_)) :: r -> unwind r | R :: r -> unwind r | L :: r -> R :: r - in + in List.rev p |> unwind |> List.rev -let state_violates_symmetry {skeleton} = +let state_violates_symmetry {skeleton;_} = let rec r = function | Abstraction(b) -> r b | Apply(f,x) -> @@ -154,7 +154,7 @@ let state_violates_symmetry {skeleton} = | _ -> false in r skeleton - + let state_successors ~maxFreeParameters cg state = let (request,g) = match follow_path state.skeleton state.path with @@ -190,7 +190,7 @@ let state_successors ~maxFreeParameters cg state = free_parameters = state.free_parameters + new_free_parameters; path = unwind_path state.path; skeleton = modify_skeleton state.skeleton candidate state.path;} - | first_argument :: later_arguments -> (* nonterminal *) + | _first_argument :: later_arguments -> (* nonterminal *) let application_template = List.fold_left argument_requests ~init:candidate ~f:(fun e (a,at) -> Apply(e,primitive_unknown a at)) @@ -213,12 +213,13 @@ let best_first_enumeration ?lower_bound:(lower_bound=None) | None -> 9999.0 | Some(ub) -> ub in - + let completed = ref [] in - + let pq = Heap.create ~cmp:(fun s1 s2 -> + let open Float in let c = s1.cost -. s2.cost in if c < 0. then -1 else if c > 0. then 1 else 0) () in @@ -229,6 +230,7 @@ let best_first_enumeration ?lower_bound:(lower_bound=None) assert (not (state_finished best)); (* Printf.printf "\nParent:\n%s\n" (string_of_state best); *) state_successors ~maxFreeParameters:maxFreeParameters cg best |> List.iter ~f:(fun child -> + let open Float in if state_finished child then (if lower_bound <= child.cost && child.cost < upper_bound then completed := child :: !completed else ()) @@ -239,10 +241,10 @@ let best_first_enumeration ?lower_bound:(lower_bound=None) (!completed, Heap.to_list pq) - + (* Depth first enumeration *) let enumeration_timeout = ref Float.max_value;; -let enumeration_timed_out() = Unix.time() > !enumeration_timeout;; +let enumeration_timed_out() = Float.(>) (Unix.time()) !enumeration_timeout;; let set_enumeration_timeout dt = enumeration_timeout := Unix.time() +. dt;; @@ -257,7 +259,7 @@ let rec enumerate_programs' (cg : contextual_grammar) (g: grammar) (context: tCo (callBack: program -> tContext -> float -> int -> unit) : unit = (* Enumerates programs satisfying: lowerBound <= MDL < upperBound *) (* INVARIANT: request always has the current context applied to it already *) - if enumeration_timed_out() || maximumDepth < 1 || upper_bound < 0.0 then () else + if enumeration_timed_out() || maximumDepth < 1 || Float.(<) upper_bound 0.0 then () else match request with | TCon("->",[argument_type;return_type],_) -> let newEnvironment = argument_type :: environment in @@ -273,7 +275,7 @@ let rec enumerate_programs' (cg : contextual_grammar) (g: grammar) (context: tCo candidates |> List.iter ~f:(fun (candidate, argument_types, context, ll) -> let mdl = 0.-.ll in - if mdl >= upper_bound || + if Float.(>=) mdl upper_bound || (match parent with | None -> false | Some((p,j)) -> violates_symmetry p candidate j) @@ -305,11 +307,11 @@ and (callBack: program -> tContext -> float -> int -> unit) : unit = (* Enumerates application chains satisfying: lowerBound <= MDL < upperBound *) (* returns the log likelihood of the arguments! not the log likelihood of the application! *) - if enumeration_timed_out() || maximumDepth < 1 || upper_bound < 0.0 then () else + if enumeration_timed_out() || maximumDepth < 1 || Float.(<) upper_bound 0.0 then () else match argument_requests with | [] -> (* not a function so we don't need any applications *) begin - if lower_bound <= 0. && 0. < upper_bound then + if Float.(<=) lower_bound 0. && Float.(<) 0. upper_bound then (* match f with * | Apply(Apply(Primitive(_,function_name,_),first_argument),second_argument) * when violates_commutative function_name first_argument second_argument -> () @@ -347,7 +349,7 @@ let dfs_around_skeleton cg ~maxFreeParameters ~lower_bound ~upper_bound state k let rec parent_index = function (* Given that the input is an application, what is the identity of the function, and what is the index of the argument? *) - | Apply(f,x) -> + | Apply(f,_) -> (match f with | Apply(_,_) -> let (f',n) = parent_index f in @@ -361,19 +363,19 @@ let dfs_around_skeleton cg ~maxFreeParameters ~lower_bound ~upper_bound state k let rec around e abstraction_depth ?parent:(parent=None) (* context abstraction_depth l u mfp k *) = match e with | Abstraction(body) -> - let around_body = around ~parent:None body (1+abstraction_depth) in - fun context l u mfp k -> + let around_body = around ~parent:None body (1+abstraction_depth) in + fun context l u mfp k -> around_body context l u mfp (fun body newContext ll fp -> k (Abstraction(body)) newContext ll fp) | Apply(f,x) when free x && (not (free f)) -> let around_argument = around ~parent:(Some(parent_index e)) x abstraction_depth in - fun context l u mfp k -> + fun context l u mfp k -> around_argument context l u mfp (fun x' newContext ll fp -> k (Apply(f,x')) newContext ll fp) | Apply(f,x) when free f && free x -> let around_argument = around ~parent:(Some(parent_index e)) x abstraction_depth in let around_function = around ~parent:None f abstraction_depth in - fun context l u mfp k -> + fun context l u mfp k -> around_function context 0. u mfp (fun f' context f_ll fp -> around_argument context (l+.f_ll) (u+.f_ll) (mfp - fp) @@ -385,14 +387,14 @@ let dfs_around_skeleton cg ~maxFreeParameters ~lower_bound ~upper_bound state k | Primitive(t,"??",g) -> let g = !(g |> magical) in let environment = List.drop environment (List.length environment - abstraction_depth) in - fun context l u mfp k -> + fun context l u mfp k -> let (context, t) = applyContext context t in (* Printf.printf "Enumerating around type %s mfp = %d\n" * (string_of_type t) (mfp); *) enumerate_programs' ~parent:parent cg g context t environment l u ~maxFreeParameters:mfp k | _ -> assert false - in - + in + around ~parent:None state.skeleton 0 state.context (lower_bound -. state.cost) (upper_bound -. state.cost) (maxFreeParameters - state.free_parameters) (fun e context ll _ -> k e context (ll-.state.cost)) @@ -406,12 +408,12 @@ let multicore_enumeration ?extraQuiet:(extraQuiet=false) ?final:(final=fun () -> | (None,1) -> 1 | (None,c) -> !shatter_factor*c in - + let (finished, fringe) = best_first_enumeration ~lower_bound:(Some(lb)) ~upper_bound:(Some(ub)) ~frontier_size:shatter ~maxFreeParameters:maxFreeParameters cg request in - if not extraQuiet then + if not extraQuiet then (Printf.eprintf "\t(ocaml: %d CPUs. shatter: %d. |fringe| = %d. |finished| = %d.)\n" cores shatter (List.length fringe) (List.length finished); flush_everything()); @@ -424,6 +426,7 @@ let multicore_enumeration ?extraQuiet:(extraQuiet=false) ?final:(final=fun () -> let fringe = fringe |> List.sort ~compare:(fun s1 s2 -> + let open Float in let d = s1.cost -. s2.cost in if d > 0. then 1 else if d < 0. then -1 else 0) in @@ -435,7 +438,7 @@ let multicore_enumeration ?extraQuiet:(extraQuiet=false) ?final:(final=fun () -> (* ignore(time_it "Evaluated finished programs" (fun () -> *) finished |> List.iter ~f:(fun s -> k s.skeleton (0.-.s.cost)); final() :: fringe_results - else begin + else begin List.iter ~f:continuation fringe; finished |> List.iter ~f:(fun s -> k s.skeleton (0.-.s.cost)); [final()] @@ -449,13 +452,13 @@ let enumerate_programs ?extraQuiet:(extraQuiet=false) ?maxFreeParameters:(maxFre (* Strip out the recursion operators because they only occur at the top level *) let strip_recursion g = - {g with + {g with library = g.library |> List.filter ~f:(fun (p,_,_,_) -> not (is_recursion_primitive p)) |> (* sort library by number of arguments so that it will tend to explore shorter things first *) List.sort ~compare:(fun (_,a,_,_) (_,b,_,_) -> List.length (arguments_of_type a) - List.length (arguments_of_type b)) } - in + in let g' = {no_context=strip_recursion cg.no_context; variable_context=strip_recursion cg.variable_context; contextual_library=cg.contextual_library |> List.filter_map ~f:(fun (program, grammars) -> @@ -467,9 +470,9 @@ let enumerate_programs ?extraQuiet:(extraQuiet=false) ?maxFreeParameters:(maxFre in let k' = - if definitely_recursive then begin + if definitely_recursive then begin fun p l -> - let p' = + let p' = match p with | Abstraction(body) -> if variable_is_bound ~height:0 body then (* Used the fix point operator *) @@ -484,7 +487,7 @@ let enumerate_programs ?extraQuiet:(extraQuiet=false) ?maxFreeParameters:(maxFre end else k in - + multicore_enumeration ~extraQuiet ~maxFreeParameters:maxFreeParameters ~final:final ~cores:nc g' request' lb ub k' @@ -502,13 +505,13 @@ let test_recursive_enumeration () = l; flush_everything(); let t = infer_program_type empty_context [] p |> snd in - ignore(unify empty_context t request); + ignore(unify empty_context t request : tContext); Printf.printf "%s\n" (t |> string_of_type)) ;; -let test_best_enumeration() = +let test_best_enumeration() = let g = primitive_grammar [ differentiable_placeholder; (* differentiable_zero; *) @@ -520,13 +523,12 @@ let test_best_enumeration() = * differentiable_multiply; *) ] in - let mfp = 4 in + let mfp = 4 in let request = treal @> treal in - let frontier = ref [] in + let frontier = ref [] in let k p l = frontier := (string_of_program p, l) :: !frontier; assert (number_of_free_parameters p <= mfp); Printf.printf "%s\t%d\n" (string_of_program p) (number_of_free_parameters p) in - let open Sys in - enumerate_programs ~maxFreeParameters:mfp ~final:(fun () -> List.take !frontier 5) ~nc:(Sys.argv.(1) |> Int.of_string) (g |> make_dummy_contextual) request 0. (Sys.argv.(2) |> Float.of_string) k + enumerate_programs ~maxFreeParameters:mfp ~final:(fun () -> List.take !frontier 5) ~nc:((Sys.get_argv()).(1) |> Int.of_string) (g |> make_dummy_contextual) request 0. ((Sys.get_argv()).(2) |> Float.of_string) k ;; diff --git a/solvers/funarray.ml b/solvers/funarray.ml index 916a004e4..91648d6af 100644 --- a/solvers/funarray.ml +++ b/solvers/funarray.ml @@ -1,12 +1,12 @@ (* - funarray.ml - - Port of Chris Okasaki's purely functional - random-access list to CAML - - Construct a random-access list with + funarray.ml + + Port of Chris Okasaki's purely functional + random-access list to CAML + + Construct a random-access list with cons elt empty - + Access an element of a random-access list with lookup ls idx @@ -14,7 +14,7 @@ update ls idx new - ported by Will Benton, 10/5/2004 + ported by Will Benton, 10/5/2004 distributed under the GNU GPL *) @@ -31,21 +31,21 @@ exception Empty let rec fatree_lookup size tree index = match (tree, index) with (FALeaf(x), 0) -> x - | (FALeaf(x), i) -> raise Subscript - | (FANode(x,t1,t2), 0) -> x - | (FANode(x,t1,t2), i) -> + | (FALeaf(_x), _i) -> raise Subscript + | (FANode(x,_t1,_t2), 0) -> x + | (FANode(_x,t1,t2), i) -> let size' = size / 2 in - if i <= size' then + if i <= size' then fatree_lookup size' t1 (i - 1) else fatree_lookup size' t2 (i - 1 - size') let rec fatree_update size tree index y = - match (tree, index) with - (FALeaf(x), 0) -> FALeaf(y) - | (FALeaf(x), i) -> raise Subscript - | (FANode(x,t1,t2), 0) -> FANode(y,t1,t2) - | (FANode(x,t1,t2), i) -> + match (tree, index) with + (FALeaf(_x), 0) -> FALeaf(y) + | (FALeaf(_x), _i) -> raise Subscript + | (FANode(_x,t1,t2), 0) -> FANode(y,t1,t2) + | (FANode(x,t1,t2), i) -> let size' = size / 2 in if i <= size' then FANode(x,fatree_update size' t1 (i - 1) y,t2) @@ -54,7 +54,7 @@ let rec fatree_update size tree index y = let rec lookup ls i = match (ls, i) with - ([], i) -> raise Subscript + ([], _) -> raise Subscript | ((size, t) :: rest, i) -> if i < size then fatree_lookup size t i @@ -63,7 +63,7 @@ let rec lookup ls i = let rec update ls i y = match (ls, i) with - ([], i) -> raise Subscript + ([], _) -> raise Subscript | ((size, t) :: rest, i) -> if i < size then (size, fatree_update size t i y) :: rest @@ -75,7 +75,7 @@ let empty = [] let isempty ls = match ls with [] -> true - | ((size,t) :: rest) -> false + | ((_size,_t) :: _rest) -> false let cons x ls = match (ls) with @@ -86,17 +86,16 @@ let cons x ls = (1, FALeaf(x)) :: ls | xls -> (1, FALeaf(x)) :: xls -let head ls = +let head ls = match ls with [] -> raise Empty - | (size, FALeaf(x)) :: rest -> x - | (size, FANode(x,t1,t2)) :: rest -> x - + | (_size, FALeaf(x)) :: _rest -> x + | (_size, FANode(x,_t1,_t2)) :: _rest -> x + let tail ls = - match ls with + match ls with [] -> raise Empty - | (size, FALeaf(x)) :: rest -> rest - | (size, FANode(x,t1,t2)) :: rest -> + | (_size, FALeaf(_x)) :: rest -> rest + | (size, FANode(_x,t1,t2)) :: rest -> let size' = size / 2 in (size', t1) :: (size', t2) :: rest - diff --git a/solvers/funarray.mli b/solvers/funarray.mli index 3b4f0ccbd..eb333c13e 100644 --- a/solvers/funarray.mli +++ b/solvers/funarray.mli @@ -1,12 +1,12 @@ (* funarray.mli - - Port of Chris Okasaki's purely functional + + Port of Chris Okasaki's purely functional random-access list to CAML: supports random access - and pure functional updates AND supports head/tail + and pure functional updates AND supports head/tail operations in O(1) - - Construct a random-access list with + + Construct a random-access list with cons elt empty -> returns elt::empty @@ -20,7 +20,7 @@ --- - ported by Will Benton, 10/5/2004 + ported by Will Benton, 10/5/2004 distributed under the GNU GPL *) diff --git a/solvers/geomDrawFile.ml b/solvers/geomDrawFile.ml index d27987394..f04dbb6e8 100644 --- a/solvers/geomDrawFile.ml +++ b/solvers/geomDrawFile.ml @@ -1,5 +1,4 @@ open GeomLib -open Plotter open Renderer open Interpreter open Printf @@ -7,9 +6,9 @@ open Lexing exception MalformedProgram of string -let _ = Random.self_init () +let _ : unit = Random.self_init () -let print_pos lexbuf = +let print_pos lexbuf = let pos = lexbuf.lex_curr_p in sprintf "(line %d ; column %d)" pos.pos_lnum (pos.pos_cnum - pos.pos_bol) @@ -36,14 +35,14 @@ let file_to_string filename = close_in ic ; s -let _ = +let _ : unit = if (Array.length Sys.argv != 2) then failwith "You need to provide exactly one argument, namely the name of the .LoG file you want to parse and execute, and this program will output a .png file accordingly." ; let program_string = file_to_string Sys.argv.(1) in (try (match read_program program_string with | Some (program) -> let canvas = interpret program - and canvas_norm = interpret_normal program + (* and canvas_norm = interpret_normal program *) and prefix = Filename.chop_suffix Sys.argv.(1) ".LoG" in (try Unix.mkdir prefix 0o777 with Unix.Unix_error(Unix.EEXIST, _, _) -> ()) ; diff --git a/solvers/geomDrawLambdaString.ml b/solvers/geomDrawLambdaString.ml index 5051c53fc..49856d693 100644 --- a/solvers/geomDrawLambdaString.ml +++ b/solvers/geomDrawLambdaString.ml @@ -9,7 +9,7 @@ let empty28 = Bigarray.(Array1.create int8_unsigned c_layout (28*28)) (*let empty64 = Bigarray.(Array1.create int8_unsigned c_layout (64*64))*) (*let empty256 = Bigarray.(Array1.create int8_unsigned c_layout (256*256))*) -let _ = Bigarray.Array1.fill empty28 0 ; Random.self_init () +let _ :unit = Bigarray.Array1.fill empty28 0 ; Random.self_init () let npp data = @@ -18,7 +18,7 @@ let npp data = done ; print_int (data.{((Bigarray.Array1.dim data) - 1)}) -let print_pos lexbuf = +let print_pos lexbuf = let pos = lexbuf.lex_curr_p in Printf.sprintf "(line %d ; column %d)" pos.pos_lnum (pos.pos_cnum - pos.pos_bol) @@ -40,7 +40,7 @@ let read_program program_string = program with e -> (print_endline program_string ; raise e) -let _ = +let _ : unit = let output_img = Sys.argv.(1) in let noise = (String.equal Sys.argv.(2) "noise") in let program_string = Sys.argv.(3) in diff --git a/solvers/geomGenerate.ml b/solvers/geomGenerate.ml index b86f2a07e..33cd57f38 100644 --- a/solvers/geomGenerate.ml +++ b/solvers/geomGenerate.ml @@ -5,7 +5,7 @@ open Printf open Images open Generator -let _ = Random.self_init () +let _ : unit = Random.self_init () let gen_name () = @@ -58,4 +58,3 @@ let () = end end with MalformedProgram(s) -> () done - diff --git a/solvers/geomLib/Generator.ml b/solvers/geomLib/Generator.ml index 78af60dd0..716768384 100644 --- a/solvers/geomLib/Generator.ml +++ b/solvers/geomLib/Generator.ml @@ -110,11 +110,11 @@ let rec get_random_var : string list -> var = fun var_list -> (*| n when n < cumsum_unit Indefinite -> Indefinite*) | n when n < cumsum_unit (Name "") -> begin - match var_list with + match var_list with | [] -> get_random_var var_list | _ -> Name(pick_random_in_list var_list) end - | n -> + | _ -> raise (InternalGenerationError("in total_var_unit")) else match Random.float total_var_op with @@ -143,7 +143,7 @@ let rec_generate_random : string list -> (string list * shapeprogram) = let var = if b then Some(get_random_var var_list) else None in (var_list,Turn(var)) | n when n < cumsum_program (Embed(dummy_program)) -> - let l,p = helper var_list in + let _,p = helper var_list in (var_list,Embed(p)) | n when n < cumsum_program (Concat(dummy_program,dummy_program)) -> let l,p = helper var_list in @@ -196,6 +196,6 @@ let generate_random : unit -> shapeprogram = ([],Concat(p1,p2)) | _ -> let var = get_random_var [] in - let l,p = rec_generate_random [] in + let _,p = rec_generate_random [] in ([], Repeat(Some var,p)) in p diff --git a/solvers/geomLib/Interpreter.ml b/solvers/geomLib/Interpreter.ml index bb1f74398..101abd132 100644 --- a/solvers/geomLib/Interpreter.ml +++ b/solvers/geomLib/Interpreter.ml @@ -1,9 +1,6 @@ -open Hashtbl -open Random open Printf open Plotter open Utils2 -open Renderer type var = Name of string | Unit @@ -130,12 +127,12 @@ let valuesCostVar : var -> int = | Unit -> 1 (*| Indefinite -> 1*) | Name _ -> 1 - | Double v' -> 1 - | Half v' -> 1 - | Next v' -> 1 - | Prev v' -> 1 - | Opposite v' -> 1 - | Divide(v1,v2) -> 1 + | Double _ -> 1 + | Half _ -> 1 + | Next _ -> 1 + | Prev _ -> 1 + | Opposite _ -> 1 + | Divide(_,_) -> 1 let costVar : var option -> int = let rec helper v = match v with @@ -278,7 +275,7 @@ let interpret ?factor:(factor=1.) ?noise:(noise=false) shapeprogram = let n' = int_of_float (match n with | None -> 2. | Some v -> evaluateVar v htbl_var) in - for i = 1 to n' do + for _ = 1 to n' do inter ~sizes pr htbl_var curr_state done | Integrate (f, pen, (speed,accel,angularSpeed,angularAccel)) -> @@ -301,7 +298,7 @@ let interpret ?factor:(factor=1.) ?noise:(noise=false) shapeprogram = curr_state.angularSpeed <- angularSpeed ; curr_state.angularAccel <- angularAccel ; let pen = match pen with | None -> true | Some b -> b in - for i = 1 to (int_of_float (f *. steps /. factor)) do + for _ = 1 to (int_of_float (f *. steps /. factor)) do let futur_x = curr_state.x +. (curr_state.speed *. cos(curr_state.face)) @@ -349,10 +346,10 @@ let interpret_normal ?noise:(noise=false) p = | Nop -> Nop, found | Define (_,_) -> p,found | Turn f -> (if found then Turn f else Nop),found - | Integrate(a,Some(false),c) -> + | Integrate(_,Some(false),_) -> if found then (p,found) else Nop,false - | Integrate(a,pen,c) -> p,true + | Integrate(_,_,_) -> p,true | Concat(p1,p2) -> if found then p,found else begin @@ -370,7 +367,7 @@ let interpret_normal ?noise:(noise=false) p = if f then Embed(p''),f else Nop,false end - | Repeat(v,p') -> p,found + | Repeat(_,_) -> p,found in let rec find_bit p = match p with | Turn(Some(v)) -> @@ -380,8 +377,8 @@ let interpret_normal ?noise:(noise=false) p = | Concat(p1,p2) -> let (b1,b2) = find_bit p1 in if b1 then b1,b2 else (find_bit p2) - | Embed (p) -> false,false - | Repeat (v,p) -> find_bit p + | Embed (_) -> false,false + | Repeat (_,p) -> find_bit p | _ -> false,false in let rec swap_bit p = match p with diff --git a/solvers/geomLib/Renderer.ml b/solvers/geomLib/Renderer.ml index d4d3c11a5..66233d2b2 100644 --- a/solvers/geomLib/Renderer.ml +++ b/solvers/geomLib/Renderer.ml @@ -1,7 +1,6 @@ open Vg open Gg open Plotter -open Cairo type canvas = Plotter.canvas diff --git a/solvers/geomLib/Utils2.ml b/solvers/geomLib/Utils2.ml index b865ddccd..c9501aec3 100644 --- a/solvers/geomLib/Utils2.ml +++ b/solvers/geomLib/Utils2.ml @@ -1,6 +1,5 @@ open Vg open Gg -open Plotter (* Some utils values and functions *) diff --git a/solvers/geomLib/dune b/solvers/geomLib/dune new file mode 100644 index 000000000..df2acce2e --- /dev/null +++ b/solvers/geomLib/dune @@ -0,0 +1,13 @@ +(ocamllex lambdaLexer) + +(ocamllex geomLexer) + +(menhir + (modules lambdaParser)) + +(menhir + (modules geomParser)) + +(library + (name geomLib) + (libraries vg vg.cairo cairo2)) diff --git a/solvers/geomLib/geomLexer.mll b/solvers/geomLib/geomLexer.mll index ed5c9b00d..592b53b0a 100644 --- a/solvers/geomLib/geomLexer.mll +++ b/solvers/geomLib/geomLexer.mll @@ -76,4 +76,3 @@ rule read = (*}*) (*| _ { raise (SyntaxError ("Illegal string character: " ^ Lexing.lexeme lexbuf)) }*) (*| eof { raise (SyntaxError ("String is not terminated")) }*) - diff --git a/solvers/geomLib/jbuild b/solvers/geomLib/jbuild deleted file mode 100644 index 1d49d6199..000000000 --- a/solvers/geomLib/jbuild +++ /dev/null @@ -1,14 +0,0 @@ -(jbuild_version 1) - -(ocamllex (lambdaLexer)) -(ocamllex (geomLexer)) - -(menhir - ((modules (lambdaParser)))) - -(menhir - ((modules (geomParser)))) - -(library - ((name geomLib) - (libraries (vg vg.cairo)))) diff --git a/solvers/geomLib/lambdaLexer.mll b/solvers/geomLib/lambdaLexer.mll index 6d7705dfa..a2b23741f 100644 --- a/solvers/geomLib/lambdaLexer.mll +++ b/solvers/geomLib/lambdaLexer.mll @@ -1,5 +1,4 @@ { - open Lexing open LambdaParser exception SyntaxError of string } diff --git a/solvers/geomTest.ml b/solvers/geomTest.ml index 99f97ade5..46dff4ee5 100644 --- a/solvers/geomTest.ml +++ b/solvers/geomTest.ml @@ -2,7 +2,6 @@ open GeomLib open Plotter open Renderer open Interpreter -open Printf (*let prog = (Plumbing.concat Plumbing.integrate*) (*(Plumbing.concat (Plumbing.turn None) Plumbing.integrate))*) @@ -38,4 +37,3 @@ let () = npp l ; print_newline () ; output_canvas_png (path,box) 512 "toto.png" - diff --git a/solvers/grammar.ml b/solvers/grammar.ml index e84239c99..ab9fd4b0e 100644 --- a/solvers/grammar.ml +++ b/solvers/grammar.ml @@ -66,7 +66,7 @@ let grammar_log_weight g p = let unifying_expressions g environment request context : (program*tp list*tContext*float) list = (* given a grammar environment requested type and typing context, what are all of the possible leaves that we might use? - These could be productions in the grammar or they could be variables. + These could be productions in the grammar or they could be variables. Yields a sequence of: (leaf, argument types, context with leaf return type unified with requested type, normalized log likelihood) *) @@ -80,20 +80,20 @@ let unifying_expressions g environment request context : (program*tp list*tConte then try let context = unify context return request in - let (context,t) = applyContext context t in + let (context,t) = applyContext context t in Some((p,arguments_of_type t,context,ll)) with UnificationFailure -> None else None) in let variable_candidates = match (variable_candidates, g.continuation_type) with - | (_ :: _, Some(t)) when t = request -> + | (_ :: _, Some(t)) when equal_tp t request -> let terminal_indices = List.filter_map variable_candidates ~f:(fun (p,t,_,_) -> - if t = [] then Some(get_index_value p) else None) in - if terminal_indices = [] then variable_candidates else + if List.is_empty t then Some(get_index_value p) else None) in + if List.is_empty terminal_indices then variable_candidates else let smallest_terminal_index = fold1 min terminal_indices in variable_candidates |> List.filter ~f:(fun (p,t,_,_) -> let okay = not (is_index p) || - not (t = []) || + not (List.is_empty t) || get_index_value p = smallest_terminal_index in (* if not okay then *) (* Printf.eprintf "Pruning imperative index %s with request %s; environment=%s; smallest=%i\n" *) @@ -107,7 +107,7 @@ let unifying_expressions g environment request context : (program*tp list*tConte let nv = List.length variable_candidates |> Float.of_int |> log in let variable_candidates = variable_candidates |> List.map ~f:(fun (p,t,k,ll) -> (p,t,k,ll-.nv)) in - let grammar_candidates = + let grammar_candidates = g.library |> List.filter_map ~f:(fun (p,t,ll,u) -> try let return_type = return_of_type t in @@ -141,7 +141,7 @@ let show_summary s = let n = n |> List.map ~f:string_of_program |> join ~separator:"," in Printf.sprintf "normalizer_frequency[%s] = %f;" n f)) @ ["}"]) - + let empty_likelihood_summary() = { normalizer_frequency = Hashtbl.Poly.create(); @@ -199,7 +199,7 @@ let make_likelihood_summary g request expression = let s = empty_likelihood_summary() in let context = ref empty_context in - + let rec summarize (r : tp) (environment: tp list) (p: program) : unit = match r with (* a function - must start out with a sequence of lambdas *) @@ -215,19 +215,19 @@ let make_likelihood_summary g request expression = match List.find candidates ~f:(fun (candidate,_,_,_) -> program_equal candidate f) with | None -> s.likelihood_constant <- Float.neg_infinity - | Some(_, argument_types, newContext, functionLikelihood) -> + | Some(_, argument_types, newContext, _functionLikelihood) -> context := newContext; record_likelihood_event s f (candidates |> List.map ~f:(fun (candidate,_,_,_) -> candidate)); List.iter (List.zip_exn xs argument_types) ~f:(fun (x,x_t) -> summarize x_t environment x) in - + summarize request [] expression; s let likelihood_under_grammar g request program = make_likelihood_summary g request program |> summary_likelihood g - + @@ -264,10 +264,10 @@ let prune_contextual_grammar (g : contextual_grammar) = try let k, child_type = instantiate_type empty_context child_type in let k, argument_type = instantiate_type k argument_type in - let _ = unify k child_type argument_type in + let _ : tContext = unify k child_type argument_type in true with UnificationFailure -> false)}) - in + in {no_context=g.no_context; variable_context=g.variable_context; contextual_library= @@ -295,7 +295,7 @@ let deserialize_grammar g = with UnificationFailure -> raise (Failure ("Could not type "^source)) in let logProbability = p |> member "logProbability" |> to_number in - + (e,t,logProbability,compile_unifier t)) in let continuation_type = @@ -307,10 +307,9 @@ let deserialize_grammar g = g let serialize_grammar {logVariable; continuation_type; library} = - let open Yojson.Basic in - let j : json = + let j : Yojson.Basic.t = `Assoc(["logVariable",`Float(logVariable); - "productions",`List(library |> List.map ~f:(fun (e,t,l,_) -> + "productions",`List(library |> List.map ~f:(fun (e,_,l,_) -> `Assoc(["expression",`String(string_of_program e); "logProbability",`Float(l)])))] @ match continuation_type with @@ -318,7 +317,7 @@ let serialize_grammar {logVariable; continuation_type; library} = | Some(it) -> ["continuationType", serialize_type it]) in j - + let deserialize_contextual_grammar j = let open Yojson.Basic.Util in @@ -327,8 +326,8 @@ let deserialize_contextual_grammar j = contextual_library = j |> member "productions" |> to_list |> List.map ~f:(fun production -> let e = production |> member "program" |> to_string in - let e = - try e |> parse_program |> get_some + let e = + try e |> parse_program |> get_some with _ -> Printf.eprintf "Could not parse `%s'\n" e; @@ -337,6 +336,6 @@ let deserialize_contextual_grammar j = let children = production |> member "arguments" |> to_list |> List.map ~f:deserialize_grammar in (e, children));} |> prune_contextual_grammar -let deserialize_contextual_grammar g = +let deserialize_contextual_grammar g = try deserialize_grammar g |> make_dummy_contextual with _ -> deserialize_contextual_grammar g diff --git a/solvers/jbuild b/solvers/jbuild deleted file mode 100644 index e1bfe7634..000000000 --- a/solvers/jbuild +++ /dev/null @@ -1,9 +0,0 @@ -(jbuild_version 1) - -(executables - ((names (solver compression helmholtz geomDrawLambdaString geomDrawFile geomTest logoTest logoDrawString logoSequenceString protonet-tester client versionDemo)) - (modes (native)) - (ocamlopt_flags (:standard -O3 -unboxed-types -nodynlink -w -20)) - (libraries (core re2 yojson geomLib logoLib ocaml-protoc zmq)) ;parmap - (preprocess (pps (ppx_jane))) - )) diff --git a/solvers/karel.ml b/solvers/karel.ml index 47960944b..8fa369ae8 100644 --- a/solvers/karel.ml +++ b/solvers/karel.ml @@ -6,7 +6,7 @@ open Yojson;; open Core;; -type dir_type = +type dir_type = { mutable delta_x : int; mutable delta_y : int; @@ -26,21 +26,21 @@ type hero_type = mutable dir : dir_type; };; -type game_type = +type game_type = { - mutable hero : hero_type; + mutable hero : hero_type; n : int; m : int; mutable board : (cell_occupancy array) array; };; -let make_init_board local_n local_m hero = +let make_init_board local_n local_m hero = let the_board = (Array.make_matrix local_n local_m Empty) in the_board.(hero.x).(hero.y) <- Hero; the_board;; exception Exception of string -let dir_type_to_string x = +let dir_type_to_string x = match x with |{delta_x = -1; delta_y = 0} -> "^" |{delta_x = 1; delta_y = 0} -> "V" @@ -49,7 +49,7 @@ let dir_type_to_string x = |{delta_x = x; delta_y = y} -> raise (Exception "Direction not handled");; exception Exception of string -let mixed_type_to_string x = +let mixed_type_to_string x = match x with |{delta_x = -1; delta_y = 0} -> "A"; |{delta_x = 1; delta_y = 0} -> "U"; @@ -57,7 +57,7 @@ let mixed_type_to_string x = |{delta_x = 0; delta_y = 1} -> "D"; |{delta_x = x; delta_y = y} -> raise (Exception "Direction not handled");; -let cell_type_to_string x hero_dir = +let cell_type_to_string x hero_dir = match x with |Blocked -> "#" |Empty -> "." @@ -65,14 +65,14 @@ let cell_type_to_string x hero_dir = |Hero_and_Marker -> mixed_type_to_string hero_dir |Hero -> dir_type_to_string hero_dir;; -let print_row my_array hero_dir= +let print_row my_array hero_dir= print_string "[|"; for i = 0 to ((Array.length my_array)-1) do printf "%s" (cell_type_to_string my_array.(i) hero_dir) done; print_string "|]";; -let print_matrix the_matrix hero_dir = +let print_matrix the_matrix hero_dir = print_string "[|\n"; for i = 0 to ((Array.length the_matrix)-1) do if not (phys_equal i 0) then print_string "\n" else (); @@ -80,12 +80,12 @@ let print_matrix the_matrix hero_dir = done; print_string "|]\n";; -let print_game game = +let print_game game = print_matrix game.board game.hero.dir; print_string "\n";; -let make_new_game local_n local_m = - let local_hero = {x = 0; y = 0; dir = right} in +let make_new_game local_n local_m = + let local_hero = {x = 0; y = 0; dir = right} in {hero = local_hero; n = local_n; m = local_m; board = (make_init_board local_n local_m local_hero)};; let rec set value game = function @@ -93,37 +93,37 @@ let rec set value game = function |(x, y)::t -> game.board.(x).(y) <- value; set value game t;; let remove_hero game = - let cell = game.board.(game.hero.x).(game.hero.y) in + let cell = game.board.(game.hero.x).(game.hero.y) in if cell = Hero_and_Marker then game.board.(game.hero.x).(game.hero.y) <- Marker else game.board.(game.hero.x).(game.hero.y) <- Empty;; -let set_hero game = - let cell = game.board.(game.hero.x).(game.hero.y) in +let set_hero game = + let cell = game.board.(game.hero.x).(game.hero.y) in if cell = Marker then game.board.(game.hero.x).(game.hero.y) <- Hero_and_Marker else (game.board.(game.hero.x).(game.hero.y) <- Hero);; -let invariant game = +let invariant game = if (game.board.(game.hero.x).(game.hero.y) = Hero) || (game.board.(game.hero.x).(game.hero.y) = Hero_and_Marker) then true else false;; let move_forward game = assert (invariant game); - remove_hero game; + remove_hero game; game.hero.x <- max (min (game.hero.x + game.hero.dir.delta_x) (game.n-1)) 0; game.hero.y <- max (min (game.hero.y + game.hero.dir.delta_y) (game.m-1)) 0; set_hero game;; -let put_marker game = +let put_marker game = assert (invariant game); let hero = game.hero in game.board.(hero.x).(hero.y) <- Hero_and_Marker;; -let pick_marker game = +let pick_marker game = assert (invariant game); let board = game.board in let hero = game.hero in if board.(hero.x).(hero.y) = Hero_and_Marker then game.board.(hero.x).(hero.y) <- Hero else ();; -let turn_left game = +let turn_left game = assert (invariant game); let rec rotate_left = function |{delta_x = -1; delta_y = 0} -> {delta_x = 0; delta_y = -1} @@ -131,10 +131,10 @@ let turn_left game = |{delta_x = 0; delta_y = -1} -> {delta_x = 1; delta_y = 0} |{delta_x = 0; delta_y = 1} -> {delta_x = -1; delta_y = 0} |{delta_x = x; delta_y = y} -> raise (Exception "Direction not handled") - in + in game.hero.dir <- (rotate_left game.hero.dir);; -let turn_right game = +let turn_right game = assert (invariant game); let rec rotate_right = function |{delta_x = -1; delta_y = 0} -> {delta_x = 0; delta_y = 1} @@ -142,12 +142,12 @@ let turn_right game = |{delta_x = 0; delta_y = -1} -> {delta_x = -1; delta_y = 0} |{delta_x = 0; delta_y = 1} -> {delta_x = 1; delta_y = 0} |{delta_x = x; delta_y = y} -> raise (Exception "Direction not handled") - in + in game.hero.dir <- (rotate_right game.hero.dir);; -let execute_primitives game primitives = - let execute_primitive primitive = +let execute_primitives game primitives = + let execute_primitive primitive = match primitive with |"turnRight" -> turn_right game |"move" -> move_forward game @@ -155,13 +155,14 @@ let execute_primitives game primitives = |"putMarker" -> put_marker game |"pickMarker" -> pick_marker game |_ -> raise (Exception "Primitive not handled") - in + in let rec aux = function |[] -> () |x :: t -> execute_primitive x; print_string x; print_string "\n"; print_game game; aux t; in aux primitives;; +let _ : unit = let new_game = make_new_game 5 6 in print_game new_game; @@ -173,7 +174,7 @@ set Blocked new_game [(1,2); (2, 3); (3, 4)]; print_game new_game; -execute_primitives new_game +execute_primitives new_game ["move"; "pickMarker"; "turnRight"; "move"; "pickMarker"; "move"; "turnLeft"; "move"; "pickMarker"; "turnRight"; "move"; "pickMarker"; "turnLeft"; "move"; "pickMarker"; ]; (* @@ -217,7 +218,7 @@ and primitive_type = } and program_block_type = MAIN_type of main_type| PRIMITIVE_type of primitive_type | IF_type of if_type| IFELSE_type of ifelse_type| ELSE_type of else_type| REPEAT_type of repeat_type| WHILE_type of while_type;; -let execute_program game program_instructions = +let execute_program game program_instructions = let rec execute_instruction open_brackets acc_body = function |"DEF"::t -> assert (acc_body = [] && open_brackets = []); execute_instruction open_brackets acc_body t; |"run"::t -> assert (acc_body = [] && open_brackets = []); execute_instruction open_brackets acc_body t; @@ -248,7 +249,7 @@ let execute_program game program_instructions = |"putMarker"::t ->() |"pickMarker"::t ->()*) (*|r_string::t -> ()*) - in + in ();; *) @@ -299,23 +300,23 @@ print_game new_game;*) (* ["DEF", "run", "m(", "REPEAT", "R=3", "r(", "IF", "c(", "not", "c(", "leftIsClear", "c)", "c)", "i(", "move", "WHILE", "c(", "noMarkersPresent", "c)", "w(", "REPEAT", "R=2", "r(", "IFELSE", "c(", "not", "c(", "leftIsClear", "c)", "c)", "i(", "putMarker", "i)", "ELSE", "e(", "putMarker", "e)", "r)", "turnLeft", "w)", "i)", "turnLeft", "r)", "move", "turnLeft", "turnLeft", "m)"] -{"examples": +{"examples": [ { - "actions": ["move", "putMarker"], - "example_index": 0, - "inpgrid_json": + "actions": ["move", "putMarker"], + "example_index": 0, + "inpgrid_json": { - "blocked": "", - "cols": 3, - "crashed": false, + "blocked": "", + "cols": 3, + "crashed": false, "hero": "11:0:east", "markers": "2:0:1 0:1:8", "rows": 14 - }, - "outgrid_json": + }, + "outgrid_json": { - "blocked": "", + "blocked": "", "cols": 3, "crashed": false, "hero": "11:1:east", "markers": "11:1:1 2:0:1 0:1:8", "rows": 14 - }, + }, }, - ] + ] *) diff --git a/solvers/list_synthesizer.ml b/solvers/list_synthesizer.ml index 2da37cf31..a06e81528 100644 --- a/solvers/list_synthesizer.ml +++ b/solvers/list_synthesizer.ml @@ -63,9 +63,9 @@ let list_grammar = primitive_is_square; primitive_greater_than;] -let _ = +let _ :unit = let t = supervised_task "filter-squares" (tlist tint @> tlist tint) - [([1;2;1;9;4;3;2],[1;1;9;4])] + [([1;2;1;9;4;3;2],[1;1;9;4])] in enumerate_for_task ~timeout:30000 list_grammar t diff --git a/solvers/logoDrawString.ml b/solvers/logoDrawString.ml index 63aaf22b2..93e0c1a19 100644 --- a/solvers/logoDrawString.ml +++ b/solvers/logoDrawString.ml @@ -4,7 +4,6 @@ open LogoLib open LogoInterpreter open VGWrapper -open Differentiation open Program let smooth_logo_wrapper t2t k s0 = @@ -15,23 +14,23 @@ let smooth_logo_wrapper t2t k s0 = let dx = x2-.x1 in let dy = y2-.y1 in let l = dx*.dx+.dy*.dy |> sqrt in - if l <= e then [command] else + if Float.(<=) l e then [command] else let f = e/.l in let x = x1 +. f*.dx in - let y = y1 +. f*.dy in + let y = y1 +. f*.dy in (SEGMENT(x1,y1,x,y)) :: smooth_path (SEGMENT(x,y,x2,y2)) - in + in (p |> List.map ~f:smooth_path |> List.concat, s) -let _ = +let _: unit = let open Yojson.Basic.Util in - let j = Yojson.Basic.from_channel Pervasives.stdin in + let j = Yojson.Basic.from_channel Stdlib.stdin in let open Yojson.Basic in let open Utils in let open Timeout in let jobs = to_list (member "jobs" j) in - + let pretty = try to_bool (member "pretty" j) with _ -> false @@ -46,8 +45,9 @@ let _ = in let trim s = - if s.[0] = '"' then String.sub s 1 (String.length s - 2) else s - in + let open Char in + if s.[0] = '"' then String.sub s ~pos:1 ~len:(String.length s - 2) else s + in let b0 = Bigarray.(Array1.create int8_unsigned c_layout (8*8)) in Bigarray.Array1.fill b0 0 ; @@ -63,25 +63,25 @@ let _ = let animate = try to_bool (member "animate" j) with _ -> false - in - + in + let p = to_string (member "program" j) |> trim in let p = safe_get_some (Printf.sprintf "Could not parse %s\n" p) (parse_program p) in if animate then match export with | None -> assert (false) - | Some(export) -> + | Some(export) -> let p = analyze_lazy_evaluation p in let turtle = run_lazy_analyzed_with_arguments p [] in let turtle = if smooth_pretty then smooth_logo_wrapper turtle else turtle in let cs = animate_turtle turtle in - List.iteri cs (fun j c -> + List.iteri cs ~f:(fun j c -> output_canvas_png ~pretty c size (Printf.sprintf "%s_%09d.png" export j)); - Sys.command (Printf.sprintf "convert -delay 1 -loop 0 %s_*.png %s.gif" - export export); - Sys.command (Printf.sprintf "rm %s_*.png" export); + ignore(Sys.command (Printf.sprintf "convert -delay 1 -loop 0 %s_*.png %s.gif" + export export) : int); + ignore(Sys.command (Printf.sprintf "rm %s_*.png" export) : int); `String("exported") - else + else try match run_for_interval timeout (fun () -> let p = analyze_lazy_evaluation p in @@ -91,9 +91,9 @@ let _ = let array = canvas_to_1Darray c size in c, array, cost) with | None -> `String("timeout") - | Some(c, array, cost) -> + | Some(c, array, cost) -> let bx = canvas_to_1Darray c 8 in - if bx = b0 then `String("empty") + if Core.Poly.equal bx b0 then `String("empty") else match export with | Some(fn) -> (output_canvas_png ~pretty c size fn; diff --git a/solvers/logoLib/Colors.ml b/solvers/logoLib/Colors.ml index 5186c9aa0..3e9f34f95 100644 --- a/solvers/logoLib/Colors.ml +++ b/solvers/logoLib/Colors.ml @@ -48,9 +48,8 @@ let rgb2hsl r g b = let interpolate_color (r1,g1,b1) (r2,g2,b2) = let (h1,s1,l1) = rgb2hsl r1 g1 b1 in let (h2,s2,l2) = rgb2hsl r2 g2 b2 in - fun distance -> + fun distance -> let h = h1 +. (h2-.h1)*.distance in let s = s1 +. (s2-.s1)*.distance in let l = l1 +. (l2-.l1)*.distance in hsl2rgb h s l - diff --git a/solvers/logoLib/VGWrapper.ml b/solvers/logoLib/VGWrapper.ml index f096e078c..1e971295f 100644 --- a/solvers/logoLib/VGWrapper.ml +++ b/solvers/logoLib/VGWrapper.ml @@ -19,13 +19,13 @@ let moveto_np c x y = P.sub (P2.v x y) c let lineto_np c x y = P.line (P2.v x y) c let circle_np c x y = (Vg.P.circle (Gg.P2.v x y) 0.1) c -let moveto_p = fun (c,(ox,oy)) x y -> - (((P.empty >> (P.sub (P2.v x y))),0.)::c),(x,y) +let moveto_p = fun (c,(_ox,_oy)) x y -> + (((P.empty |> (P.sub (P2.v x y))),0.)::c),(x,y) let lineto_p = fun (c,(ox,oy)) x y -> let l = sqrt ((ox-.x)*.(ox-.x) +. (oy-.y)*.(oy-.y)) in - ((P.empty >> (P.sub (P2.v ox oy)) >> (P.line (P2.v x y))),l)::c,(x,y) + ((P.empty |> (P.sub (P2.v ox oy)) |> (P.line (P2.v x y))),l)::c,(x,y) let circle_p = fun (c,(ox,oy)) x y -> - ((P.empty >> (P.sub (P2.v ox oy)) >> (P.circle (Gg.P2.v x y) 0.1)),0.)::c,(x,y) + ((P.empty |> (P.sub (P2.v ox oy)) |> (P.circle (Gg.P2.v x y) 0.1)),0.)::c,(x,y) let rec convert_canvas c = match c with | [] -> (P.sub (Gg.P2.v 0. 0.) P.empty) @@ -117,5 +117,3 @@ let display ba = prerr_newline () done ; prerr_newline () - - diff --git a/solvers/logoLib/dune b/solvers/logoLib/dune new file mode 100644 index 000000000..3407e402a --- /dev/null +++ b/solvers/logoLib/dune @@ -0,0 +1,3 @@ +(library + (name logoLib) + (libraries vg vg.cairo cairo2)) diff --git a/solvers/logoLib/jbuild b/solvers/logoLib/jbuild deleted file mode 100644 index ad7853fd8..000000000 --- a/solvers/logoLib/jbuild +++ /dev/null @@ -1,5 +0,0 @@ -(jbuild_version 1) - -(library - ((name logoLib) - (libraries (vg vg.cairo)))) diff --git a/solvers/logoLib/logoInterpreter.ml b/solvers/logoLib/logoInterpreter.ml index 5028138e6..648330a8a 100644 --- a/solvers/logoLib/logoInterpreter.ml +++ b/solvers/logoLib/logoInterpreter.ml @@ -20,8 +20,8 @@ let logo_NOP : turtle = fun s -> ([], s) let init_state () = {x = d_from_origin; y = d_from_origin; t = 0.; p = true} let flush_everything () = - Pervasives.flush stdout; - Pervasives.flush stderr + Stdlib.flush stdout; + Stdlib.flush stderr let center_logo_list (l : logo_instruction list) : logo_instruction list = let rec minimum = function @@ -32,12 +32,12 @@ let center_logo_list (l : logo_instruction list) : logo_instruction list = | [] -> assert (false) | [x] -> x | h :: t -> max h (maximum t) - in + in match l with | [] -> [] | _ -> let xs = l |> List.map (function | (SEGMENT(x,_,x',_)) -> [x-.d_from_origin; - x'-.d_from_origin;]) |> List.concat in + x'-.d_from_origin;]) |> List.concat in let ys = l |> List.map (function | (SEGMENT(_,y,_,y')) -> [y-.d_from_origin; y'-.d_from_origin;]) |> List.concat in let x0 = xs |> minimum in @@ -52,16 +52,16 @@ let center_logo_list (l : logo_instruction list) : logo_instruction list = x'-.dx+.d_from_origin, y'-.dy+.d_from_origin)) let logo_contained_in_canvas (l : logo_instruction list) = - let okay p = p >= 0.0 && p <= 2.*.d_from_origin in + let okay p = p >= 0.0 && p <= 2.*.d_from_origin in List.for_all (function | (SEGMENT(a,b,c,d)) -> okay a && okay b && okay c && okay d) l - + let pp_logo_instruction i = match i with | SEGMENT(x1,y1,x2,y2) -> Printf.eprintf "segment{%f,%f,%f,%f}" x1 y1 x2 y2 - + let pp_turtle t = let l,_ = (t logo_NOP) (init_state ()) in List.iter @@ -72,7 +72,7 @@ let pp_turtle t = l ; prerr_newline () -let eval_turtle ?sequence (t2t : turtle -> turtle) = +let eval_turtle ?sequence:_ (t2t : turtle -> turtle) = let p,_ = (t2t logo_NOP) (init_state ()) in let p = center_logo_list p in let c = ref (new_canvas ()) in @@ -81,7 +81,7 @@ let eval_turtle ?sequence (t2t : turtle -> turtle) = let t = init_state () in moveto t.x t.y ; let total_cost = ref 0. in - let rec eval_instruction i = match i with + let eval_instruction i = match i with | SEGMENT(x1,y1,x2,y2) -> (total_cost := !total_cost +. (sqrt ((x1-.x2)*.(x1-.x2) +. (y1-.y2)*.(y1-.y2))); moveto x1 y1; @@ -90,16 +90,16 @@ let eval_turtle ?sequence (t2t : turtle -> turtle) = List.iter eval_instruction p ; !c,!total_cost -let animate_turtle ?sequence (t2t : turtle -> turtle) = +let animate_turtle (t2t : turtle -> turtle) = let p,_ = (t2t logo_NOP) (init_state ()) in let p = center_logo_list p in - let draw_list p = + let draw_list p = let c = ref (new_canvas ()) in let lineto x y = (c := (lineto !c x y)) and moveto x y = (c := (moveto !c x y)) in let t = init_state () in moveto t.x t.y ; - let rec eval_instruction i = match i with + let eval_instruction i = match i with | SEGMENT(x1,y1,x2,y2) -> (moveto x1 y1; lineto x2 y2) in List.iter eval_instruction p ; @@ -108,9 +108,9 @@ let animate_turtle ?sequence (t2t : turtle -> turtle) = let rec map_suffixes l f = match l with | [] -> [] | _ :: xs -> f l :: map_suffixes xs f - in + in List.rev (map_suffixes (List.rev p) draw_list) - + let logo_PU : turtle = fun s -> ([], {s with p = false}) @@ -121,13 +121,13 @@ let logo_RT : float -> turtle = fun angle -> fun s -> ([], {s with t = s.t +. angle}) let logo_FW : float -> turtle = - let pi = 4.0 *. atan 1.0 in + let pi = 4.0 *. atan 1.0 in fun length -> fun s -> let x' = s.x +. (length *. cos(s.t*.2.*.pi)) in let y' = s.y +. (length *. sin(s.t*.2.*.pi)) in let s' = {s with x = x'; y = y';} in - let k = if s.p then [SEGMENT(s.x,s.y,x',y')] else [] in + let k = if s.p then [SEGMENT(s.x,s.y,x',y')] else [] in (k,s') @@ -146,7 +146,7 @@ let logo_GET : (state -> turtle) -> turtle = (* let logo_SET : (state -> turtle) = fun s -> fun _ -> ([SET({s with t=s.t *. 4. *. atan(1.)})], s) *) let logo_SET : (state -> turtle) = fun s -> fun _ -> ([], s) - + let turtle_to_list turtle = let l,_ = (turtle logo_NOP) (init_state ()) in l |> center_logo_list diff --git a/solvers/logoSequenceString.ml b/solvers/logoSequenceString.ml index 4e8494b58..22fe54c09 100644 --- a/solvers/logoSequenceString.ml +++ b/solvers/logoSequenceString.ml @@ -2,7 +2,6 @@ open LogoLib open LogoInterpreter open VGWrapper -open Differentiation open Program let npp data = @@ -12,7 +11,7 @@ let npp data = print_int (data.{((Bigarray.Array1.dim data) - 1)}) ; print_newline () -let _ = +let _ : unit = let str = Sys.argv.(1) and folder = Sys.argv.(2) in try @@ -24,7 +23,7 @@ let _ = let turtle = run_lazy_analyzed_with_arguments p [] in let c = eval_turtle ~sequence:(folder^"/output_") turtle in prerr_endline "evaled" ; - output_canvas_png c 512 (folder^".png") ; + output_canvas_png (fst c) 512 (folder^".png") ; prerr_endline "drawn" | _ -> () with Invalid_argument _ | Failure _ | Stack_overflow -> () diff --git a/solvers/logoTest.ml b/solvers/logoTest.ml index 4b7017729..7b63add9c 100644 --- a/solvers/logoTest.ml +++ b/solvers/logoTest.ml @@ -5,7 +5,7 @@ let pi2 = 2. *. 3.1459 let rec unfold f stop b = if stop b then [] -else +else let x, b' = f b in x :: (unfold f stop b') @@ -38,68 +38,68 @@ let star (n : int) : turtle = let line : turtle = logo_FW 1. -(*let angle : turtle =*) - (*logo_SEQ*) - (*(logo_FW logo_var_UNIT)*) - (*(logo_SEQ*) - (*(logo_RT (logo_var_HLF logo_var_UNIT))*) - (*(logo_FW logo_var_UNIT))*) +(* let angle : turtle = *) + (* logo_SEQ *) + (* (logo_FW logo_var_UNIT) *) + (* (logo_SEQ *) + (* (logo_RT (logo_var_HLF logo_var_UNIT)) *) + (* (logo_FW logo_var_UNIT)) *) -(*let square1 : turtle =*) - (*let angle =*) - (*logo_SEQ*) - (*(logo_FW logo_var_UNIT)*) - (*(logo_RT (logo_var_HLF logo_var_UNIT))*) - (*in*) - (*let half = logo_SEQ angle angle in*) - (*logo_SEQ half half*) +(* let square1 : turtle = *) + (* let angle = *) + (* logo_SEQ *) + (* (logo_FW logo_var_UNIT) *) + (* (logo_RT (logo_var_HLF logo_var_UNIT)) *) + (* in *) + (* let half = logo_SEQ angle angle in *) + (* logo_SEQ half half *) -(*let square2 : turtle =*) - (*let angle =*) - (*logo_SEQ*) - (*(logo_FW logo_var_UNIT)*) - (*(logo_RT (logo_var_HLF logo_var_UNIT)) in*) - (*List.fold_left*) - (*(fun (k : turtle) (e : float) : turtle ->*) - (*logo_SEQ*) - (*k*) - (*angle*) - (*)*) - (*logo_NOP*) - (*([0.; 1.; 2.; 3.])*) +(* let square2 : turtle = *) + (* let angle = *) + (* logo_SEQ *) + (* (logo_FW logo_var_UNIT) *) + (* (logo_RT (logo_var_HLF logo_var_UNIT)) in *) + (* List.fold_left *) + (* (fun (k : turtle) (e : float) : turtle -> *) + (* logo_SEQ *) + (* k *) + (* angle *) + (* ) *) + (* logo_NOP *) + (* ([0.; 1.; 2.; 3.]) *) -(*let spiral : int -> turtle = fun n ->*) - (*List.fold_left*) - (*(fun (k : turtle) (e : int) : turtle ->*) - (*logo_SEQ*) - (*k*) - (*(logo_SEQ*) - (*(logo_FW ((float_of_int e) /. 2.))*) - (*(logo_RT (logo_var_HLF logo_var_UNIT))*) - (*)*) - (*)*) - (*logo_NOP*) - (*(unfold*) - (*(fun x -> (x, x + 1))*) - (*(fun x -> x >= n)*) - (*0*) - (*)*) +(* let spiral : int -> turtle = fun n -> *) + (* List.fold_left *) + (* (fun (k : turtle) (e : int) : turtle -> *) + (* logo_SEQ *) + (* k *) + (* (logo_SEQ *) + (* (logo_FW ((float_of_int e) /. 2.)) *) + (* (logo_RT (logo_var_HLF logo_var_UNIT)) *) + (* ) *) + (* ) *) + (* logo_NOP *) + (* (unfold *) + (* (fun x -> (x, x + 1)) *) + (* (fun x -> x >= n) *) + (* 0 *) + (* ) *) -let _ = - (*let c1 = eval_turtle line in*) - (*let c2 = eval_turtle angle in*) - (*let c3 = eval_turtle square1 in*) - (*let c4 = eval_turtle square2 in*) - (*pp_turtle square1;*) - (*pp_turtle square2;*) - (*VGWrapper.output_canvas_png c1 28 "line_l.png" ;*) - (*VGWrapper.output_canvas_png c2 28 "angle_l.png" ;*) - (*VGWrapper.output_canvas_png c3 28 "square1_l.png" ;*) - (*VGWrapper.output_canvas_png c4 28 "square2_l.png" ;*) - (*let _ = eval_turtle ~sequence:("seqSp") (spiral 18)*) - let _ = eval_turtle ~sequence:("seqSt") (star 12) +let _ : unit = + (* let c1 = eval_turtle line in *) + (* let c2 = eval_turtle angle in *) + (* let c3 = eval_turtle square1 in *) + (* let c4 = eval_turtle square2 in *) + (* pp_turtle square1; *) + (* pp_turtle square2; *) + (* VGWrapper.output_canvas_png c1 28 "line_l.png" ; *) + (* VGWrapper.output_canvas_png c2 28 "angle_l.png" ; *) + (* VGWrapper.output_canvas_png c3 28 "square1_l.png" ; *) + (* VGWrapper.output_canvas_png c4 28 "square2_l.png" ; *) + (* let _ = eval_turtle ~sequence:("seqSp") (spiral 18) *) + let _ : VGWrapper.canvas * float = eval_turtle ~sequence:("seqSt") (fun _ -> (star 12)) in - (*pp_turtle (spiral 8) ;*) - (*VGWrapper.output_canvas_png s8 512 "spiral8_l.png" ;*) + (* pp_turtle (spiral 8) ; *) + (* VGWrapper.output_canvas_png s8 512 "spiral8_l.png" ; *) print_endline "done" diff --git a/solvers/parallel.ml b/solvers/parallel.ml index 08b481dfd..f0e9a0d77 100644 --- a/solvers/parallel.ml +++ b/solvers/parallel.ml @@ -6,7 +6,7 @@ open Utils let parallel_do nc actions = let finished_actions = ref 0 in let number_of_actions = List.length actions in - + let children = ref [] in let actions = ref actions in @@ -27,7 +27,7 @@ let parallel_do nc actions = (* wait for something to die *) let (p,_) = Unix.wait `My_group in - children := List.filter !children ~f:(fun p' -> not (p = p')); + children := List.filter !children ~f:(fun p' -> not (Pid.(=) p p')); (* Printf.printf "DEATH\n"; * flush_everything(); *) incr finished_actions @@ -61,7 +61,7 @@ let pmap ?processes:(processes=4) ?bsize:(bsize=0) f input output = Unix.close rd; let start_idx = !next_idx in let answer = Array.init (end_idx start_idx - start_idx + 1) - (fun i -> f (input (i+start_idx))) in + ~f:(fun i -> f (input (i+start_idx))) in let chan = Unix.out_channel_of_descr wt in Marshal.to_channel chan (start_idx, answer) [Marshal.Closures]; Out_channel.close chan; @@ -80,25 +80,25 @@ let pmap ?processes:(processes=4) ?bsize:(bsize=0) f input output = ~write:[] ~except:[] ~timeout:`Never () in List.iter ~f:(fun descr -> let chan = Unix.in_channel_of_descr descr in - let pid = List.Assoc.find_exn ~equal:(=) !in_streams descr + let pid = List.Assoc.find_exn ~equal:Unix.File_descr.equal !in_streams descr and start_idx, answer = Marshal.from_channel chan in - ignore (Unix.waitpid pid); + ignore (Unix.waitpid pid: Core.Unix.Exit_or_signal.t); In_channel.close chan; - Array.blit answer 0 output start_idx (Array.length answer); + Array.blit ~src:answer ~src_pos:0 ~dst:output ~dst_pos:start_idx ~len:(Array.length answer); total_computed := Array.length answer + !total_computed) recvs.read; - in_streams := List.filter ~f:(fun (stream,_) -> not (List.mem ~equal:(=) recvs.read stream)) !in_streams; + in_streams := List.filter ~f:(fun (stream,_) -> not (List.mem ~equal:Unix.File_descr.equal recvs.read stream)) !in_streams; done; output let parallel_map ~nc l ~f = let input_array = Array.of_list l in - let output_array = Array.create (Array.length input_array) None in - let output_array = + let output_array = Array.create ~len:(Array.length input_array) None in + let output_array = pmap ~processes:(min (Array.length input_array) nc) ~bsize:1 (fun x -> Some(f x)) (Array.get input_array) output_array - in + in Out_channel.flush stdout; Array.to_list output_array |> List.map ~f:(safe_get_some "parallel_map") @@ -106,7 +106,7 @@ let parallel_work ~nc ?chunk:(chunk=0) ~final actions = if nc = 1 then begin actions |> List.iter ~f:(fun a -> a()); [final()] - end else + end else let chunk = match chunk with | 0 -> List.length actions / nc | x -> x @@ -155,13 +155,13 @@ let parallel_work ~nc ?chunk:(chunk=0) ~final actions = ~write:[] ~except:[] ~timeout:`Never () in List.iter ~f:(fun descr -> let chan = Unix.in_channel_of_descr descr in - let pid = List.Assoc.find_exn ~equal:(=) !in_streams descr + let pid = List.Assoc.find_exn ~equal:Unix.File_descr.equal !in_streams descr and (newly_completed, answer) = Marshal.from_channel chan in - ignore (Unix.waitpid pid); + ignore (Unix.waitpid pid : Core.Unix.Exit_or_signal.t); In_channel.close chan; finished_actions := !finished_actions + newly_completed; outputs := answer :: !outputs) recvs.read; - in_streams := List.filter ~f:(fun (stream,_) -> not (List.mem ~equal:(=) recvs.read stream)) !in_streams; + in_streams := List.filter ~f:(fun (stream,_) -> not (List.mem ~equal:Unix.File_descr.equal recvs.read stream)) !in_streams; done; !outputs diff --git a/solvers/parser.ml b/solvers/parser.ml index 22157dd7e..6f4a83588 100644 --- a/solvers/parser.ml +++ b/solvers/parser.ml @@ -3,10 +3,10 @@ open Core type 'a parsing = (string*int -> ('a*int) list) let return_parse (x : 'a) : 'a parsing = - fun (s,n) -> [(x,n)] + fun (_,n) -> [(x,n)] let parse_failure : 'a parsing = - fun (s,n) -> [] + fun (_,_) -> [] let bind_parse (x : 'a parsing) (f : 'a -> 'b parsing) : 'b parsing = fun (s,n) -> @@ -22,7 +22,7 @@ let constant_parser (k : string) : unit parsing = fun (s,n) -> let rec check consumed = if consumed = String.length k then true else - if n + consumed >= String.length s || s.[n + consumed] <> k.[consumed] then false else + if n + consumed >= String.length s || Char.(<>) s.[n + consumed] k.[consumed] then false else check (consumed + 1) in if check 0 then [(),n + String.length k] else [] @@ -32,7 +32,7 @@ let token_parser ?can_be_empty:(can_be_empty = false) (element : char -> bool) : let rec check consumed = if n + consumed >= String.length s || (not (element s.[n + consumed])) then [] else s.[n + consumed] :: check (consumed + 1) - in + in let token = check 0 in if (not can_be_empty) && List.length token = 0 then [] else let token = String.concat ~sep:"" (token |> List.map ~f:(String.make 1)) in diff --git a/solvers/physics.ml b/solvers/physics.ml index c84826356..cc155a34e 100644 --- a/solvers/physics.ml +++ b/solvers/physics.ml @@ -5,7 +5,7 @@ open Differentiation open Program open Type open Task - + let tvector = make_ground "vector" let tobject = make_ground "object" let tfield = make_ground "field" @@ -18,42 +18,41 @@ type physics_field = | VelocityField ;; -primitive "get-field" (tobject @> tfield @> tvector) +let _ : unit = +ignore(primitive "get-field" (tobject @> tfield @> tvector) (fun o f -> match f with | PositionField -> o.position - | VelocityField -> o.velocity);; -primitive "position" tfield PositionField;; -primitive "velocity" tfield VelocityField;; -primitive "get-position" (tobject @> tvector) - (fun o -> o.position);; -primitive "get-velocity" (tobject @> tvector) - (fun o -> o.velocity);; -primitive "mass" (tobject @> treal) - (fun o -> o.mass);; -primitive "*v" (treal @> tvector @> tvector) - (fun r v -> v |> List.map ~f:(fun v' -> v'*&r));; -primitive "/v" (tvector @> treal @> tvector) - (fun v r -> v |> List.map ~f:(fun v' -> v'/&r));; -primitive "+v" (tvector @> tvector @> tvector) + | VelocityField -> o.velocity) : program); +ignore(primitive "position" tfield PositionField : program); +ignore(primitive "velocity" tfield VelocityField : program); +ignore(primitive "get-position" (tobject @> tvector) + (fun o -> o.position) : program); +ignore(primitive "get-velocity" (tobject @> tvector) + (fun o -> o.velocity) : program); +ignore(primitive "mass" (tobject @> treal) + (fun o -> o.mass) : program); +ignore(primitive "*v" (treal @> tvector @> tvector) + (fun r v -> v |> List.map ~f:(fun v' -> v'*&r)) : program); +ignore(primitive "/v" (tvector @> treal @> tvector) + (fun v r -> v |> List.map ~f:(fun v' -> v'/&r)) : program); +ignore(primitive "+v" (tvector @> tvector @> tvector) (fun a b -> - List.map2_exn a b ~f:(+&));; -primitive "-v" (tvector @> tvector @> tvector) + List.map2_exn a b ~f:(+&)) : program); +ignore(primitive "-v" (tvector @> tvector @> tvector) (fun a b -> - List.map2_exn a b ~f:(-&));; -primitive "yhat" tvector [~$0.;~$1.];; -primitive "normalize" (tvector @> tvector) + List.map2_exn a b ~f:(-&)) : program); +ignore(primitive "yhat" tvector [~$0.;~$1.] : program); +ignore(primitive "normalize" (tvector @> tvector) (fun v -> let l = v |> List.map ~f:square |> List.reduce_exn ~f:(+&) |> square_root in - v |> List.map ~f:(fun v' -> v'/&l));; -primitive "sq" (treal @> treal) square;; -primitive "dp" (tvector @> tvector @> treal) - (fun a b -> List.map2_exn a b ~f:( *&) |> List.reduce_exn ~f:(+&));; -primitive "vector-length" (tvector @> treal) - (fun v -> v |> List.map ~f:(fun x -> x *& x) |> List.reduce_exn ~f:(+&) |> square_root);; + v |> List.map ~f:(fun v' -> v'/&l)) : program); +ignore(primitive "sq" (treal @> treal) square : program); +ignore(primitive "dp" (tvector @> tvector @> treal) + (fun a b -> List.map2_exn a b ~f:( *&) |> List.reduce_exn ~f:(+&)) : program); +ignore(primitive "vector-length" (tvector @> treal) + (fun v -> v |> List.map ~f:(fun x -> x *& x) |> List.reduce_exn ~f:(+&) |> square_root) : program); + - - - register_special_task "physics" (fun extra ?timeout:(timeout=0.01) name request _ -> @@ -90,9 +89,9 @@ register_special_task "physics" in let unpack t = - if t = tvector then unpack_vector else - if t = tobject then unpack_object else - if t = treal then unpack_real else assert (false) + if equal_tp t tvector then unpack_vector else + if equal_tp t tobject then unpack_object else + if equal_tp t treal then unpack_real else assert (false) in let arguments, return = arguments_and_return_of_type request in @@ -140,13 +139,10 @@ register_special_task "physics" ~iterations:(if List.length parameters = 0 then 0 else steps) parameters average_loss in + let open Float in match lossThreshold with | None -> 0. -. d*.parameterPenalty -. n *. average_loss /. temperature | Some(t) -> - if List.for_all l ~f:(fun {data=Some(this_loss)} -> this_loss < t) + if [@warning "-8"] List.for_all l ~f:(fun {data=Some(this_loss);_} -> this_loss < t) then 0. -. d*.parameterPenalty else log 0.)}) - - - - diff --git a/solvers/polynomial.ml b/solvers/polynomial.ml index fc98562ac..ea61eaaab 100644 --- a/solvers/polynomial.ml +++ b/solvers/polynomial.ml @@ -10,7 +10,7 @@ open Compression open EC let maximumCoefficient = 9 - + let polynomial_tasks = (0--maximumCoefficient) |> List.map ~f:(fun a -> (0--maximumCoefficient) |> List.map ~f:(fun b -> @@ -37,6 +37,6 @@ let polynomial_grammar = ] - -let _ = + +let _ : unit = exploration_compression polynomial_tasks polynomial_grammar ~keepTheBest:3 10000 1 ~alpha:10. diff --git a/solvers/pregex.ml b/solvers/pregex.ml index aae7811ef..b7eb2faf8 100644 --- a/solvers/pregex.ml +++ b/solvers/pregex.ml @@ -1,5 +1,6 @@ open Core +module Heap = Pairing_heap open Timeout open Task open Utils @@ -7,9 +8,9 @@ open Program open Type open Yojson.Basic.Util - + type str = String of char list | Dot | D | S | W | L | U -[@@deriving compare] +[@@deriving compare, equal] let dot_ls = List.rev (String.to_list_rev "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t") let d_ls = List.rev (String.to_list_rev "0123456789") @@ -23,16 +24,16 @@ let get_character_class = function | D -> d_ls | S -> s_ls | W -> w_ls | L -> l_ls | U -> u_ls | _ -> assert (false) -type pregex = +type pregex = | Constant of str | Kleene of pregex | Plus of pregex | Maybe of pregex | Alt of pregex * pregex | Concat of pregex * pregex -[@@deriving compare] +[@@deriving compare, equal] -let rec string_of_str = function +let string_of_str = function | String(c) -> String.of_char_list c | Dot -> "." | D -> "[0-9]" @@ -57,19 +58,19 @@ and hash_constant = function | String(cs) -> List.fold_right ~init:17 ~f:(fun c a -> Hashtbl.hash (Hashtbl.hash c,a)) cs | c -> Hashtbl.hash c - + let rec canonical_regex r = let empty_regex = Constant(String([])) in - + match r with | Constant(_) -> r | Plus(b) -> - let b = canonical_regex b in + let b = canonical_regex b in canonical_regex (Concat(b,Kleene(b))) | Kleene(b) -> let b = canonical_regex b in - if b = empty_regex then empty_regex else Kleene(b) + if equal_pregex b empty_regex then empty_regex else Kleene(b) | Maybe(b) -> Alt(empty_regex,b) |> canonical_regex (* associative rules *) | Concat(Concat(a,b),c) -> canonical_regex (Concat(a,Concat(b,c))) @@ -77,8 +78,8 @@ let rec canonical_regex r = | Concat(a,b) -> let a = canonical_regex a in let b = canonical_regex b in - if a = empty_regex then b else - if b = empty_regex then a else + if equal_pregex a empty_regex then b else + if equal_pregex b empty_regex then a else Concat(a, b) | Alt(a,b) -> let a = canonical_regex a in @@ -97,11 +98,11 @@ type match_state = { let rec match_regex random (state : match_state) r return = match r with | Constant(String(s)) -> - if List.take state.match_target (List.length s) = s then + if List.equal Char.(=) (List.take state.match_target (List.length s)) s then return {state with match_target=List.drop state.match_target (List.length s)} | Constant(k) -> (match state.match_target with - | hd :: tl when List.mem ~equal:(=) (get_character_class k) hd -> + | hd :: tl when List.mem ~equal:Char.(=) (get_character_class k) hd -> return {match_likelihood=state.match_likelihood-.(get_character_class k |> List.length |> Float.of_int |> log); match_target=tl} @@ -144,9 +145,9 @@ let match_regex regex s = {match_target=s; match_likelihood=0.;} regex (fun final -> - if final.match_target = [] then + if List.is_empty final.match_target then final_state := Some(final)); - while !final_state = None && not (Heap.is_empty h) do + while Option.is_none !final_state && not (Heap.is_empty h) do let _,k = Heap.pop_exn h in k() done; @@ -155,74 +156,76 @@ let match_regex regex s = | _ -> log 0. ;; -if false then begin - Printf.eprintf "%f\n" - (match_regex (Concat(Kleene(Alt(Constant(D),Constant(S))),Constant(String([])))) ['9';' ';]); - flush_everything(); - assert (false) -end;; +let _ : unit = + if false then begin + Printf.eprintf "%f\n" + (match_regex (Concat(Kleene(Alt(Constant(D),Constant(S))),Constant(String([])))) ['9';' ';]); + flush_everything(); + assert (false) + end;; + + - - type continuation = pregex option * string -let rec try_remove_prefix prefix str = +let rec try_remove_prefix prefix str = (* returns a none if can't remove, else the removed list *) + let open Char in match (prefix, str) with | ([], l) -> Some(l) | (_, []) -> None | (ph::pt, sh::st) -> if ph = sh then try_remove_prefix pt st else None;; let consumeConst c char_list = - match char_list with + match char_list with | [] -> (match c with (* We are done! We didn't need to match anything and we have nothing *) | String([]) -> [(None, []), 0.] (* We failed - we needed to terminate matching because the string is up *) | _ -> []) - | hd :: tl -> - match c with - | String(ls) -> - (match try_remove_prefix ls char_list with + | hd :: tl -> + match c with + | String(ls) -> + (match try_remove_prefix ls char_list with | None -> [] | Some(remainder) -> [ (None, remainder), 0. ]) | _ -> - let character_class = get_character_class c in - if List.mem ~equal:(=) character_class hd + let character_class = get_character_class c in + if List.mem ~equal:Char.(=) character_class hd then [(None, tl), -. log (List.length character_class |> Float.of_int)] else [] - -let f_kleene a partial = + +let f_kleene a partial = match partial with | ((None, remainder), score) -> ((Some(Kleene(a)), remainder), score +. log 0.5) | ((Some(r), remainder), score) -> ((Some(Concat(r, Kleene(a))), remainder), score +. log 0.5);; (* is this order of r and a correct?*) -let f_plus a partial = +let f_plus a partial = match partial with | ((None, remainder), score) -> ((Some(Kleene(a)), remainder), score) | ((Some(r), remainder), score) -> ((Some(Concat(r, Kleene(a))), remainder), score) ;; (* is this order of r and a correct?*) -let f_maybe a ((r, remainder), score) = ((r, remainder), score +. log 0.5) ;; +let f_maybe _a ((r, remainder), score) = ((r, remainder), score +. log 0.5) ;; let f_alt ((r, remainder), score) = ((r, remainder), score +. log 0.5 ) ;; -let f_concat a b partial = - match partial with +let f_concat _a b partial = + match partial with | ((None, remainder), score) -> ((Some(b), remainder), score) | ((Some(r), remainder), score) -> ((Some(Concat(r, b)), remainder), score) ;; -let rec kleeneConsume a str = +let rec kleeneConsume a str = ((None, str), log 0.5 ) :: (consume (Some(a), str) |> List.map ~f:(f_kleene a)) -and plusConsume a str = +and plusConsume a str = consume (Some(a), str) |> List.map ~f:(f_plus a) -and maybeConsume a str = +and maybeConsume a str = ((None, str), log 0.5 ) :: (consume (Some(a), str) |> List.map ~f:(f_maybe a)) and concatConsume a b str = List.map (consume (Some(a), str)) ~f:(f_concat a b) @@ -232,8 +235,8 @@ and consume cont = (* return a list of continuation, score tuples? *) | (None, []) -> assert false (* no regular expression and nothing to consume - this is a match, and should have been caught earlier *) | (None, _ :: _) -> [] (* no regular expression and things to consume - not a match *) | (Some(Constant(c)), str) -> consumeConst c str - | (Some(Kleene(a)), str) -> kleeneConsume a str - | (Some(Plus(a)), str) -> plusConsume a str + | (Some(Kleene(a)), str) -> kleeneConsume a str + | (Some(Plus(a)), str) -> plusConsume a str | (Some(Maybe(a)), str) -> maybeConsume a str | (Some(Alt(a,b)), str) -> List.map (consume (Some(a), str) @ consume (Some(b), str)) ~f:f_alt | (Some(Concat(a,b)), str) -> concatConsume a b str @@ -241,29 +244,29 @@ and consume cont = (* return a list of continuation, score tuples? *) let preg_match preg str = (* dikjstras *) - let cmp = fun (_, score1) (_, score2) -> Float.compare score2 score1 in + let cmp = fun (_, score1) (_, score2) -> Float.compare score2 score1 in let heap = Heap.create ~cmp:cmp () in Heap.add heap ((Some(preg), str), 0.); let visited = Hash_set.Poly.create() in let solution = ref None in - let consume_loop (cont_old, score_old) = + let consume_loop (cont_old, score_old) = consume cont_old |> List.iter ~f:(fun (cont, score) -> - if not (Hash_set.mem visited cont) then begin + if not (Hash_set.mem visited cont) then begin Hash_set.add visited cont; let newscore = score +. score_old in match cont with - | (None, []) -> + | (None, []) -> solution := Some(newscore) (* TODO output *) | _ -> Heap.add heap (cont, newscore) end) - in + in - while !solution = None && not (Heap.top heap = None) do + while Option.is_none !solution && Option.is_some (Heap.top heap) do match Heap.pop heap with | Some(partial) -> consume_loop partial - | None -> assert false + | None -> assert false done; match !solution with @@ -274,38 +277,39 @@ let preg_match preg str = (* dikjstras *) let tregex = make_ground "pregex" ;; let empty_regex = Constant(String([]));; +let _ : unit = ignore(primitive "r_dot" (tregex @> tregex) - (fun k -> Concat(Constant(Dot),k)));; + (fun k -> Concat(Constant(Dot),k)) : program); ignore(primitive "r_d" (tregex @> tregex) - (fun k -> Concat(Constant(D),k)));; + (fun k -> Concat(Constant(D),k)) : program); ignore(primitive "r_s" (tregex @> tregex) - (fun k -> Concat(Constant(S),k)));; + (fun k -> Concat(Constant(S),k)) : program); ignore(primitive "r_w" (tregex @> tregex) - (fun k -> Concat(Constant(W),k)));; + (fun k -> Concat(Constant(W),k)) : program); ignore(primitive "r_l" (tregex @> tregex) - (fun k -> Concat(Constant(L),k)));; + (fun k -> Concat(Constant(L),k)) : program); ignore(primitive "r_u" (tregex @> tregex) - (fun k -> Concat(Constant(U),k)));; + (fun k -> Concat(Constant(U),k)) : program); ignore(primitive "r_kleene" ((tregex @> tregex) @> tregex @> tregex) - (fun b k -> Concat(Kleene(b empty_regex),k)));; + (fun b k -> Concat(Kleene(b empty_regex),k)) : program); ignore(primitive "r_plus" ((tregex @> tregex) @> tregex @> tregex) - (fun b k -> Concat(Plus(b empty_regex),k)));; + (fun b k -> Concat(Plus(b empty_regex),k)) : program); ignore(primitive "r_maybe" ((tregex @> tregex) @> tregex @> tregex) - (fun b k -> Concat(Maybe(b empty_regex),k)));; + (fun b k -> Concat(Maybe(b empty_regex),k)) : program); ignore(primitive "r_alt" ((tregex @> tregex) @> (tregex @> tregex) @> tregex @> tregex) - (fun a b k -> Concat(Alt(a empty_regex, b empty_regex),k)));; + (fun a b k -> Concat(Alt(a empty_regex, b empty_regex),k)) : program); ignore(primitive "r_const" (tregex @> tregex) - ());; + () : program);; let rec substitute_constant_regex constant p = match p with | Abstraction(b) -> Abstraction(substitute_constant_regex constant b) | Apply(f, x) -> Apply(substitute_constant_regex constant f, substitute_constant_regex constant x) | Invented(t,b) -> Invented(t, substitute_constant_regex constant b) - | Primitive(t,"r_const",_) -> constant + | Primitive(_,"r_const",_) -> constant | Index(_) | Primitive(_,_,_) -> p let disallowed_regex = Hashtbl.Poly.create ();; @@ -318,7 +322,7 @@ let build_constant_regex characters = in Abstraction(loop characters);; - +let _ : unit = [ ('#', "hash"); ('!', "bang"); @@ -354,7 +358,7 @@ let build_constant_regex characters = ('~', "tilde"); (' ', "space"); ('\t', "tab") -] |> List.iter ~f: (fun (c, name) -> Hashtbl.set disallowed_regex ~key:c ~data:name);; +] |> List.iter ~f: (fun (c, name) -> Hashtbl.set disallowed_regex ~key:c ~data:name); @@ -365,7 +369,7 @@ dot_ls |> List.iter ~f: (fun i -> | Some(datum) -> Printf.sprintf "string_%s" datum in let the_primitive = primitive name (tregex @> tregex) - (fun k -> Concat(Constant(String([i])),k)) in + (fun k -> Concat(Constant(String([i])),k)) in Hashtbl.set constant_to_regex ~key:i ~data:the_primitive);; @@ -373,11 +377,12 @@ let regex_of_program expression : pregex = run_lazy_analyzed_with_arguments (analyze_lazy_evaluation expression) [empty_regex];; (* Printf.eprintf "hello world %" *) - + +let _ : unit = register_special_task "regex" (fun extra ?timeout:(timeout=0.001) name task_type examples -> - assert (task_type = tregex @> tregex); + assert (equal_tp task_type (tregex @> tregex)); examples |> List.iter ~f:(fun (xs,_) -> assert (List.length xs = 0)); let observations : char list list = examples |> List.map ~f:(fun (_,y) -> y |> magical) in @@ -416,17 +421,18 @@ register_special_task "regex" loop observations) with | None -> log 0. - | Some(l) -> + | Some(l) -> (let cutoff_option = extra |> member "cutoff" |> to_number_option in match cutoff_option with - | None -> l - | Some(cutoff) -> + | None -> l + | Some(cutoff) -> + let open Float in if l >= cutoff then l -. (Float.of_int number_of_constants) *. const_cost else log 0.) - in + in {name; task_type; log_likelihood;} ) - + (* let _ = Printf.eprintf "\n\n\n\nLIKELIHOOD: %f\n\n\n\n" (preg_match (Alt(Constant(String(['d'])), Constant(D))) ['9'] |> exp) ;; let _ = Printf.eprintf "\n\n\n\nLIKELIHOOD: %f\n\n\n\n" ((preg_match (Constant(D)) ['9']) |> exp) ;; *) @@ -437,7 +443,7 @@ let _ = assert (preg_match (Alt(Constant(String(['k'])), Constant(D))) ['9'] = (* qs for kevin: map -> List.map list ~f:fun -implicit def - good +implicit def - good concat_lists -> List.concat [list1; list2 ...] and recursion? function defs with pattern matching? @@ -448,4 +454,3 @@ Hash_set.Poly.create() String.to_list() ref and ! Hash_set.mem candidates *) - diff --git a/solvers/program.ml b/solvers/program.ml index b8999a313..af98c0439 100644 --- a/solvers/program.ml +++ b/solvers/program.ml @@ -9,6 +9,7 @@ type program = | Apply of program*program | Primitive of tp * string * (unit ref) | Invented of tp * program +[@@deriving equal] let is_index = function |Index(_) -> true @@ -41,7 +42,7 @@ let program_children = function | _ -> [] let rec application_function = function - | Apply(f,x) -> application_function f + | Apply(f,_) -> application_function f | e -> e let rec application_parse = function @@ -57,7 +58,7 @@ let rec program_size = function let rec program_subexpressions p = - p::(List.map (program_children p) program_subexpressions |> List.concat) + p::(List.map (program_children p) ~f:program_subexpressions |> List.concat) let rec show_program (is_function : bool) = function | Index(j) -> "$" ^ string_of_int j @@ -77,8 +78,9 @@ let string_of_program = show_program false let primitive_name = function | Primitive(_,n,_) -> n | e -> raise (Failure ("primitive_name: "^string_of_program e^"not a primitive")) -let rec program_equal p1 p2 = match (p1,p2) with - | (Primitive(_,n1,_),Primitive(_,n2,_)) -> n1 = n2 +let rec program_equal p1 p2 = + match (p1,p2) with + | (Primitive(_,n1,_),Primitive(_,n2,_)) -> String.(=) n1 n2 | (Abstraction(a),Abstraction(b)) -> program_equal a b | (Invented(_,a),Invented(_,b)) -> program_equal a b | (Index(a),Index(b)) -> a = b @@ -100,7 +102,7 @@ let rec compare_program p1 p2 = match (p1,p2) with | (Primitive(_,_,_),_) -> -1 | (Invented(_,b1),Invented(_,b2)) -> compare_program b1 b2 | (Invented(_,_),_) -> -1 - + exception UnboundVariable;; let rec infer_program_type context environment p : tContext*tp = match p with @@ -128,7 +130,7 @@ let make_invention i = exception UnknownPrimitive of string - + let every_primitive : (program String.Table.t) = String.Table.create();; @@ -137,7 +139,7 @@ let lookup_primitive n = Hashtbl.find_exn every_primitive n with _ -> raise (UnknownPrimitive n) - + let [@warning "-20"] rec evaluate (environment: 'b list) (p:program) : 'a = match p with | Apply(Apply(Apply(Primitive(_,"if",_),branch),yes),no) -> @@ -155,7 +157,7 @@ let rec analyze_evaluation (p:program) : 'b list -> 'a = and yes = analyze_evaluation yes and no = analyze_evaluation no in - fun environment -> + fun environment -> if magical (branch environment) then yes environment else no environment | Abstraction(b) -> let body = analyze_evaluation b in @@ -205,7 +207,7 @@ let [@warning "-20"] rec analyze_lazy_evaluation (p:program) : (('b Lazy.t) list evaluation conditionals are function just like any other. *) | Abstraction(b) -> let body = analyze_lazy_evaluation b in - fun environment -> + fun environment -> lazy (magical @@ fun argument -> Lazy.force (body (argument::environment))) | Index(j) -> fun environment -> magical @@ List.nth_exn environment j @@ -213,7 +215,7 @@ let [@warning "-20"] rec analyze_lazy_evaluation (p:program) : (('b Lazy.t) list let analyzed_function = analyze_lazy_evaluation f and analyzed_argument = analyze_lazy_evaluation x in - fun environment -> + fun environment -> lazy ((Lazy.force @@ magical @@ analyzed_function environment) (magical @@ analyzed_argument environment)) | Primitive(_,_,v) -> fun _ -> lazy (magical (!v)) | Invented(_,i) -> @@ -275,7 +277,7 @@ let rec beta_normal_form ?reduceInventions:(reduceInventions=false) e = | None -> None end | Invented(_,b) when reduceInventions -> Some(b) - | Apply(f,x) -> begin + | Apply(f,x) -> begin match step f with | Some(f') -> Some(Apply(f',x)) | None -> match step x with @@ -286,7 +288,7 @@ let rec beta_normal_form ?reduceInventions:(reduceInventions=false) e = | _ -> None end | _ -> None - in + in match step e with | None -> e | Some(e') -> beta_normal_form ~reduceInventions e' @@ -306,7 +308,7 @@ let [@warning "-20"] primitive ?manualLaziness:(manualLaziness = false) (name : string) (t : tp) x = let number_of_arguments = arguments_of_type t |> List.length in (* Force the arguments *) - let x = if manualLaziness then x else magical @@ + let x = if manualLaziness then x else magical @@ match number_of_arguments with | 0 -> magical x | 1 -> fun a -> (magical x) (Lazy.force a) @@ -323,7 +325,7 @@ let [@warning "-20"] primitive ?manualLaziness:(manualLaziness = false) in let p = Primitive(t,name, ref (magical x)) in assert (not (Hashtbl.mem every_primitive name)); - ignore(Hashtbl.add every_primitive name p); + ignore(Hashtbl.add every_primitive ~key:name ~data:p : [ `Duplicate | `Ok ]); p (* let primitive_empty_string = primitive "emptyString" tstring "";; *) @@ -331,8 +333,8 @@ let primitive_uppercase = primitive "caseUpper" (tcharacter @> tcharacter) Char. (* let primitive_uppercase = primitive "strip" (tstring @> tstring) (fun s -> String.strip s);; *) let primitive_lowercase = primitive "caseLower" (tcharacter @> tcharacter) Char.lowercase;; let primitive_character_equal = primitive "char-eq?" (tcharacter @> tcharacter @> tboolean) Char.equal;; -let primitive_character_equal = primitive "char-upper?" (tcharacter @> tboolean) Char.is_uppercase;; -let primitive_character_equal = primitive "str-eq?" (tlist tcharacter @> tlist tcharacter @> tboolean) (fun x y -> x = y);; +let primitive_character_upper = primitive "char-upper?" (tcharacter @> tboolean) Char.is_uppercase;; +let primitive_string_equal = primitive "str-eq?" (tlist tcharacter @> tlist tcharacter @> tboolean) (fun x y -> x = y);; (* let primitive_capitalize = primitive "caseCapitalize" (tstring @> tstring) String.capitalize;; * let primitive_concatenate = primitive "concatenate" (tstring @> tstring @> tstring) ( ^ );; *) let primitive_constant_strings = [primitive "','" tcharacter ','; @@ -419,7 +421,7 @@ let rec substitute_string_constants (alternatives : char list list) e = match e | Invented(_,b) -> substitute_string_constants alternatives b | Apply(f,x) -> substitute_string_constants alternatives f |> List.map ~f:(fun f' -> substitute_string_constants alternatives x |> List.map ~f:(fun x' -> - Apply(f',x'))) |> List.concat + Apply(f',x'))) |> List.concat | Abstraction(b) -> substitute_string_constants alternatives b |> List.map ~f:(fun b' -> Abstraction(b')) | Index(_) -> [e] @@ -479,21 +481,23 @@ let primitive_nand = primitive "nand" (tboolean @> tboolean @> tboolean) (fun x let primitive_or = primitive "or" (tboolean @> tboolean @> tboolean) (fun x y -> x || y);; let primitive_greater_than = primitive "gt?" (tint @> tint @> tboolean) (fun (x: int) (y: int) -> x > y);; +let _ : unit = ignore(primitive "take-word" (tcharacter @> tstring @> tstring) (fun c s -> - List.take_while s ~f:(fun c' -> not (c = c'))));; + List.take_while s ~f:(fun c' -> not (c = c'))) : program); ignore(primitive "drop-word" (tcharacter @> tstring @> tstring) (fun c s -> - List.drop_while s ~f:(fun c' -> not (c = c')) |> List.tl |> get_some));; + List.drop_while s ~f:(fun c' -> not (c = c')) |> List.tl |> get_some) : program); ignore(primitive "abbreviate" (tstring @> tstring) (fun s -> + let open Char in let rec f = function | [] -> [] | ' ' :: cs -> f cs | c :: cs -> c :: f (List.drop_while cs ~f:(fun c' -> not (c' = ' '))) - in f s));; + in f s) : program); ignore(primitive "last-word" (tcharacter @> tstring @> tstring) (fun c s -> - List.rev s |> List.take_while ~f:(fun c' -> not (c = c')) |> List.rev));; + List.rev s |> List.take_while ~f:(fun c' -> not (c = c')) |> List.rev) : program); ignore(primitive "replace-character" (tcharacter @> tcharacter @> tstring @> tstring) (fun c1 c2 s -> - s |> List.map ~f:(fun c -> if c = c1 then c2 else c)));; + s |> List.map ~f:(fun c -> if c = c1 then c2 else c)) : program);; @@ -545,14 +549,14 @@ let primitive_integrate= primitive GeomLib.Plumbing.integrate let var_unit = primitive "var_unit" tvar GeomLib.Plumbing.var_unit -let var_unit = primitive "var_two" tvar GeomLib.Plumbing.var_two -let var_unit = primitive "var_three" tvar GeomLib.Plumbing.var_three +let var_two = primitive "var_two" tvar GeomLib.Plumbing.var_two +let var_three = primitive "var_three" tvar GeomLib.Plumbing.var_three let var_double = primitive "var_double" (tvar @> tvar) GeomLib.Plumbing.var_double let var_half = primitive "var_half" (tvar @> tvar) GeomLib.Plumbing.var_half let var_next = primitive "var_next" (tvar @> tvar) GeomLib.Plumbing.var_next let var_prev = primitive "var_prev" (tvar @> tvar) GeomLib.Plumbing.var_prev let var_opposite = primitive "var_opposite" (tvar @> tvar) GeomLib.Plumbing.var_opposite -let var_opposite = primitive "var_divide" (tvar @> tvar @> tvar) GeomLib.Plumbing.var_divide +let var_divide = primitive "var_divide" (tvar @> tvar @> tvar) GeomLib.Plumbing.var_divide let var_name = primitive "var_name" tvar GeomLib.Plumbing.var_name (* LOGO *) @@ -581,7 +585,7 @@ let logo_PD = primitive "logo_PD" LogoLib.LogoInterpreter.logo_SEQ LogoLib.LogoInterpreter.logo_PD x);; -primitive "logo_PT" +let logo_PT = primitive "logo_PT" ((turtle @> turtle) @> (turtle @> turtle)) (fun body continuation -> LogoLib.LogoInterpreter.logo_GET (fun state -> @@ -592,7 +596,7 @@ primitive "logo_PT" (if original_state then LogoLib.LogoInterpreter.logo_PD else LogoLib.LogoInterpreter.logo_PU) continuation)))) - + let logo_GET = primitive "logo_GET" (tstate @> turtle @> turtle) @@ -631,18 +635,18 @@ let logo_GETSET = primitive "logo_GETSET" -let logo_S2A = primitive "logo_UA" (tangle) (1.) -let logo_S2A = primitive "logo_UL" (tlength) (1.) +let logo_UA = primitive "logo_UA" (tangle) (1.) +let logo_UL = primitive "logo_UL" (tlength) (1.) -let logo_S2A = primitive "logo_ZA" (tangle) (0.) -let logo_S2A = primitive "logo_ZL" (tlength) (0.) +let logo_ZA = primitive "logo_ZA" (tangle) (0.) +let logo_ZL = primitive "logo_ZL" (tlength) (0.) let logo_IFTY = primitive "logo_IFTY" (tint) (20) -let logo_IFTY = primitive "logo_epsL" (tlength) (0.05) -let logo_IFTY = primitive "logo_epsA" (tangle) (0.025) +let logo_epsL = primitive "logo_epsL" (tlength) (0.05) +let logo_epsA = primitive "logo_epsA" (tangle) (0.025) -let logo_IFTY = primitive "line" +let line = primitive "line" (turtle @> turtle) (fun z -> LogoLib.LogoInterpreter.logo_SEQ @@ -654,13 +658,13 @@ let logo_IFTY = primitive "line" let logo_DIVA = primitive "logo_DIVA" (tangle @> tint @> tangle) (fun a b -> a /. (float_of_int b) ) -let logo_DIVA = primitive "logo_MULA" +let logo_MULA = primitive "logo_MULA" (tangle @> tint @> tangle) (fun a b -> a *. (float_of_int b) ) -let logo_DIVA = primitive "logo_DIVL" +let logo_DIVL = primitive "logo_DIVL" (tlength @> tint @> tlength) (fun a b -> a /. (float_of_int b) ) -let logo_DIVA = primitive "logo_MULL" +let logo_MULL = primitive "logo_MULL" (tlength @> tint @> tlength) (fun a b -> a *. (float_of_int b) ) @@ -669,10 +673,10 @@ let logo_SUBA = primitive "logo_SUBA" (tangle @> tangle @> tangle) ( -. ) let logo_ADDL = primitive "logo_ADDL" (tlength @> tlength @> tlength) ( +. ) let logo_SUBL = primitive "logo_SUBL" (tlength @> tlength @> tlength) ( -. ) -let _ = primitive "logo_forLoop" +let _ : program = primitive "logo_forLoop" (tint @> (tint @> turtle @> turtle) @> turtle @> turtle) (fun i f z -> List.fold_right (0 -- (i-1)) ~f ~init:z) -let _ = primitive "logo_forLoopM" +let _ : program = primitive "logo_forLoopM" (tint @> (tint @> turtle) @> turtle @> turtle) (fun n body k0 -> ((List.map (0 -- (n-1)) ~f:body)) @@ -680,13 +684,13 @@ let _ = primitive "logo_forLoopM" ~f:(LogoLib.LogoInterpreter.logo_SEQ) ~init:k0 ) - + (*let logo_CHEAT = primitive "logo_CHEAT" (ttvar @> turtle) LogoLib.LogoInterpreter.logo_CHEAT*) (*let logo_CHEAT2 = primitive "logo_CHEAT2" (ttvar @> turtle) LogoLib.LogoInterpreter.logo_CHEAT2*) (*let logo_CHEAT3 = primitive "logo_CHEAT3" (ttvar @> turtle) LogoLib.LogoInterpreter.logo_CHEAT3*) (*let logo_CHEAT4 = primitive "logo_CHEAT4" (ttvar @> turtle) LogoLib.LogoInterpreter.logo_CHEAT4*) -let default_recursion_limit = 20;; +(* let default_recursion_limit = 20;; *) let rec unfold x p h n = if p x then [] else h x :: unfold (n x) p h n @@ -702,8 +706,8 @@ let primitive_fold = primitive "fold" (tlist t0 @> t1 @> (t0 @> t1 @> t1) @> t1) let default_recursion_limit = ref 50;; let set_recursion_limit l = default_recursion_limit := l;; exception RecursionDepthExceeded of int;; - -let fixed_combinator argument body = + +let fixed_combinator argument body = (* strict with respect to body but lazy with respect argument *) (* body expects to be passed 2 thunks *) let body = Lazy.force body in @@ -726,10 +730,10 @@ let fixed_combinator2 argument1 argument2 body = let body = Lazy.force body in let recursion_limit = ref !default_recursion_limit in - let rec fix x y = + let rec fix x y = let r a b = decr recursion_limit; - if !recursion_limit > 0 then + if !recursion_limit > 0 then fix a b else raise (RecursionDepthExceeded(!default_recursion_limit)) in body (lazy r) x y @@ -746,7 +750,9 @@ let primitive_recursion2 = fixed_combinator2;; -let is_recursion_of_arity a = function +let is_recursion_of_arity a t = + let open String in + match t with | Primitive(_,n,_) -> ("fix"^(Int.to_string a)) = n | _ -> false @@ -757,7 +763,7 @@ let is_recursion_primitive = function let program_parser : program parsing = - let token = token_parser (fun c -> Char.is_alphanum c || List.mem ~equal:( = ) + let token = token_parser (fun c -> Char.is_alphanum c || List.mem ~equal:Char.(=) ['_';'-';'?';'/';'.';'*';'\'';'+';','; '>';'<';'@';'|';] c) in let whitespace = token_parser ~can_be_empty:true Char.is_whitespace in @@ -778,7 +784,7 @@ let program_parser : program parsing = let v = v |> Float.of_string in Primitive(treal, "real", ref (v |> magical)) |> return_parse)) in - + let rec program_parser () : program parsing = (application () <|> primitive <|> variable <|> invented() <|> abstraction() <|> fixed_real) @@ -809,7 +815,7 @@ let program_parser : program parsing = program_parser()%%(fun b -> constant_parser ")"%%(fun _ -> return_parse (nabstractions (Int.of_string n) b)))))) - + and application_sequence (maybe_function : program option) : program parsing = whitespace%%(fun _ -> match maybe_function with @@ -817,11 +823,11 @@ let program_parser : program parsing = program_parser () %%(fun f -> application_sequence (Some(f))) | Some(f) -> (return_parse f) <|> (program_parser () %%(fun x -> application_sequence (Some(Apply(f,x)))))) - - + + and application () = constant_parser "(" %% (fun _ -> - application_sequence None %% (fun a -> + application_sequence None %% (fun a -> constant_parser ")" %% (fun _ -> return_parse a))) in @@ -836,7 +842,7 @@ let parse_program s = run_parser program_parser s * let t = canonical_type t in * Printf.printf "%s : %s\n" (string_of_program program) (string_of_type t); * assert (t = (canonical_type desired_type)) - * + * * let program_test_cases() = * test_program_inference (Abstraction(Index(0))) (t0 @> t0); * test_program_inference (Abstraction(Abstraction(Apply(Index(0),Index(1))))) (t0 @> (t0 @> t1) @> t1); @@ -844,7 +850,7 @@ let parse_program s = run_parser program_parser s * test_program_inference (Abstraction(Abstraction(Index(0)))) (t0 @> t1 @> t1); * let v : int = evaluate [] (Apply(primitive_increment, primitive0)) in * Printf.printf "%d\n" v; - * + * * ;; *) let parsing_test_case s = @@ -852,7 +858,7 @@ let parsing_test_case s = program_parser (s,0) |> List.iter ~f:(fun (p,n) -> if n = String.length s then (Printf.printf "Parsed into the program: %s\n" (string_of_program p); - assert (s = (string_of_program p)); + assert (String.(=) s (string_of_program p)); flush_everything()) else (Printf.printf "With the suffix %n, we get the program %s\n" n (string_of_program p); @@ -876,24 +882,24 @@ let parsing_test_cases() = (* program_test_cases();; *) - + let [@warning "-20"] performance_test_case() = let e = parse_program "(lambda (fix1 $0 (lambda (lambda (if (empty? $0) $0 (cons (* 2 (car $0)) ($1 (cdr $0))))))))" |> get_some in let xs = [2;1;9;3;] in let n = 10000000 in - time_it "evaluate program many times" (fun () -> + time_it "evaluate program many times" (fun () -> (0--n) |> List.iter ~f:(fun j -> if j = n then Printf.printf "%s\n" (evaluate [] e xs |> List.map ~f:Int.to_string |> join ~separator:" ") else - ignore (evaluate [] e xs))); + ignore (evaluate [] e xs : unit))); let c = analyze_evaluation e [] in - time_it "evaluate analyzed program many times" (fun () -> + time_it "evaluate analyzed program many times" (fun () -> (0--n) |> List.iter ~f:(fun j -> if j = n then Printf.printf "%s\n" (c xs |> List.map ~f:Int.to_string |> join ~separator:" ") - else - ignore(c xs))) + else + ignore(c xs : unit))) ;; @@ -911,7 +917,7 @@ let [@warning "-20"] performance_test_case() = * let e = parse_program "(lambda (fix1 (lambda (lambda (if (empty? $0) $0 (cons (\* 2 (car $0)) ($1 (cdr $0)))))) $0))" |> get_some in * Printf.printf "%s\n" (string_of_program e); * evaluate [] e [1;2;3;4;] |> List.map ~f:Int.to_string |> join ~separator:" " |> Printf.printf "%s\n"; - * + * * let e = parse_program "(lambda (lambda (fix2 (lambda (lambda (lambda (if (empty? $1) $0 (cons (car $1) ($2 (cdr $1) $0)))))) $0 $1)))" |> get_some in * infer_program_type empty_context [] e |> snd |> string_of_type |> Printf.printf "%s\n"; * evaluate [] e (0--4) [9;42;1] |> List.map ~f:Int.to_string |> join ~separator:" " |> Printf.printf "%s\n" *) @@ -929,8 +935,8 @@ let [@warning "-20"] performance_test_case() = (* let xs = [(0--10);(0--10);(0--10)] in *) (* time_it "evaluated all of the programs" (fun () -> *) - - + + (* let () = *) (* let e = parse_program "(lambda (reducei (lambda (lambda (lambda (range $0)))) empty $0))" |> get_some in *) @@ -977,9 +983,9 @@ let test_lazy_evaluation() = (arguments |> List.map ~f:Int.to_string |> join ~separator:"; "); flush_everything(); let v = run_lazy_analyzed_with_arguments a arguments in - begin + begin match string_of_type (return_of_type t) with - | "int" -> + | "int" -> Printf.printf "value = %d\n" (v |> magical) | "list" -> Printf.printf "value = %s\n" (v |> magical |> List.map ~f:Int.to_string |> join ~separator:",") @@ -1015,31 +1021,32 @@ let t_model_p = make_ground "t_model_p";; (* Puddleworld Primitive Definitions *) -ignore(primitive "true_p" (t_boolean_p) (fun x -> x));; -ignore(primitive "left_p" (t_direction_p) (fun x -> x));; -ignore(primitive "right_p" (t_direction_p) (fun x -> x));; -ignore(primitive "up_p" (t_direction_p) (fun x -> x));; -ignore(primitive "down_p" (t_direction_p) (fun x -> x));; -ignore(primitive "1_p" (t_int_p) (fun x -> x));; -ignore(primitive "2_p" (t_int_p) (fun x -> x));; -ignore(primitive "move_p" (t_object_p @> t_action_p) (fun x -> x));; -ignore(primitive "relate_p" (t_object_p @> t_object_p @> t_direction_p @> t_boolean_p) (fun x -> x));; -ignore(primitive "relate_n_p" (t_object_p @> t_object_p @> t_direction_p @> t_int_p @> t_boolean_p) (fun x -> x));; -ignore(primitive "in_half_p" (t_object_p @> t_direction_p @> t_boolean_p) (fun x -> x));; -ignore(primitive "apply_p" ((t_object_p @> t_boolean_p) @> t_object_p @> t_boolean_p) (fun x -> x));; -ignore(primitive "and__p" (t_boolean_p @> t_boolean_p @> t_boolean_p) (fun x -> x));; -ignore(primitive "max_in_dir_p" (t_object_p @> t_direction_p @> t_boolean_p) (fun x -> x));; -ignore(primitive "is_edge_p" (t_object_p @> t_boolean_p) (fun x -> x));; -ignore(primitive "grass_p" (t_object_p @> t_boolean_p) (fun x -> x));; -ignore(primitive "puddle_p" (t_object_p @> t_boolean_p) (fun x -> x));; -ignore(primitive "star_p" (t_object_p @> t_boolean_p) (fun x -> x));; -ignore(primitive "circle_p" (t_object_p @> t_boolean_p) (fun x -> x));; -ignore(primitive "triangle_p" (t_object_p @> t_boolean_p) (fun x -> x));; -ignore(primitive "heart_p" (t_object_p @> t_boolean_p) (fun x -> x));; -ignore(primitive "spade_p" (t_object_p @> t_boolean_p) (fun x -> x));; -ignore(primitive "diamond_p" (t_object_p @> t_boolean_p) (fun x -> x));; -ignore(primitive "rock_p" (t_object_p @> t_boolean_p) (fun x -> x));; -ignore(primitive "tree_p" (t_object_p @> t_boolean_p) (fun x -> x));; -ignore(primitive "house_p" (t_object_p @> t_boolean_p) (fun x -> x));; -ignore(primitive "horse_p" (t_object_p @> t_boolean_p) (fun x -> x));; -ignore(primitive "ec_unique_p" (t_model_p @> (t_object_p @> t_boolean_p) @> t_object_p) (fun x -> x));; +let _: unit = +ignore(primitive "true_p" (t_boolean_p) (fun x -> x) :program); +ignore(primitive "left_p" (t_direction_p) (fun x -> x) :program); +ignore(primitive "right_p" (t_direction_p) (fun x -> x) :program); +ignore(primitive "up_p" (t_direction_p) (fun x -> x) :program); +ignore(primitive "down_p" (t_direction_p) (fun x -> x) :program); +ignore(primitive "1_p" (t_int_p) (fun x -> x) :program); +ignore(primitive "2_p" (t_int_p) (fun x -> x) :program); +ignore(primitive "move_p" (t_object_p @> t_action_p) (fun x -> x) :program); +ignore(primitive "relate_p" (t_object_p @> t_object_p @> t_direction_p @> t_boolean_p) (fun x -> x) :program); +ignore(primitive "relate_n_p" (t_object_p @> t_object_p @> t_direction_p @> t_int_p @> t_boolean_p) (fun x -> x) :program); +ignore(primitive "in_half_p" (t_object_p @> t_direction_p @> t_boolean_p) (fun x -> x) :program); +ignore(primitive "apply_p" ((t_object_p @> t_boolean_p) @> t_object_p @> t_boolean_p) (fun x -> x) :program); +ignore(primitive "and__p" (t_boolean_p @> t_boolean_p @> t_boolean_p) (fun x -> x) :program); +ignore(primitive "max_in_dir_p" (t_object_p @> t_direction_p @> t_boolean_p) (fun x -> x) :program); +ignore(primitive "is_edge_p" (t_object_p @> t_boolean_p) (fun x -> x) :program); +ignore(primitive "grass_p" (t_object_p @> t_boolean_p) (fun x -> x) :program); +ignore(primitive "puddle_p" (t_object_p @> t_boolean_p) (fun x -> x) :program); +ignore(primitive "star_p" (t_object_p @> t_boolean_p) (fun x -> x) :program); +ignore(primitive "circle_p" (t_object_p @> t_boolean_p) (fun x -> x) :program); +ignore(primitive "triangle_p" (t_object_p @> t_boolean_p) (fun x -> x) :program); +ignore(primitive "heart_p" (t_object_p @> t_boolean_p) (fun x -> x) :program); +ignore(primitive "spade_p" (t_object_p @> t_boolean_p) (fun x -> x) :program); +ignore(primitive "diamond_p" (t_object_p @> t_boolean_p) (fun x -> x) :program); +ignore(primitive "rock_p" (t_object_p @> t_boolean_p) (fun x -> x) :program); +ignore(primitive "tree_p" (t_object_p @> t_boolean_p) (fun x -> x) :program); +ignore(primitive "house_p" (t_object_p @> t_boolean_p) (fun x -> x) :program); +ignore(primitive "horse_p" (t_object_p @> t_boolean_p) (fun x -> x) :program); +ignore(primitive "ec_unique_p" (t_model_p @> (t_object_p @> t_boolean_p) @> t_object_p) (fun x -> x) :program);; diff --git a/solvers/protonet-tester.ml b/solvers/protonet_tester.ml similarity index 98% rename from solvers/protonet-tester.ml rename to solvers/protonet_tester.ml index be1e6d551..8d642d43d 100644 --- a/solvers/protonet-tester.ml +++ b/solvers/protonet_tester.ml @@ -2,7 +2,7 @@ open Unix open Program -let _ = +let _ : unit = let idRef = Sys.argv.(1) and p = Sys.argv.(2) in let s_in, s_out = @@ -33,4 +33,3 @@ let _ = Printf.sprintf "Raw dist:\t%f\nProposal:\t%f" log_likelihood (-. (100. *. log_likelihood)) ) - diff --git a/solvers/recognition.ml b/solvers/recognition.ml index 372c8a15f..cb95edffb 100644 --- a/solvers/recognition.ml +++ b/solvers/recognition.ml @@ -1,8 +1,8 @@ open Core.Std open Task - -let export_task_features (tasks_and_targets : ((task*(float list)) list)) (testing : task list) (f : string) : unit = + +let export_task_features (tasks_and_targets : ((task*(float list)) list)) (testing : task list) (f : string) : unit = let open Yojson.Basic.Util in let serialize_vector v = `List(v |> List.map ~f:(fun f -> `Float(f))) diff --git a/solvers/sfg.ml b/solvers/sfg.ml index 3c4955bf5..b3f40af54 100644 --- a/solvers/sfg.ml +++ b/solvers/sfg.ml @@ -30,7 +30,7 @@ let string_of_categorized_grammar g = ", the production probabilities are:\n"^ "logVariable = "^(Float.to_string (variable_value v))^"\n"^ (p |> List.map ~f:(fun (f,t,l) -> Printf.sprintf "%f\t%s\t%s" (variable_value l) (string_of_type t) (string_of_fragment f)) |> join ~separator:"\n")^"\n") |> join ~separator:"\n") - + in s | _ -> raise (Failure "string_of_categorized_grammar") @@ -39,7 +39,7 @@ let categorized_of_fragment_grammar (f : fragment_grammar) = {logVariables = (1--number_of_productions) |> List.map ~f:(fun _ -> random_variable ()); productionProbabilities = (1--number_of_productions) |> List.map ~f:(fun _ -> f.fragments |> List.map ~f:(fun (f,t,_) -> (f,t,random_variable ())))} - + let likelihood_under_sfg (g : sfg) (request : tp) (expression : program) : variable = (* Any chain of applications could be broken up at any point by a fragment. This enumerates all of the different ways of breaking up an @@ -74,36 +74,36 @@ let likelihood_under_sfg (g : sfg) (request : tp) (expression : program) : varia List.map ~f:(fun (i,p,t,k,ll) -> (i+1,p,t,k,ll-&z)) candidates in - + let rec likelihood (context : tContext) (environment : tp list) (request : tp) (p : program) (production : int) : (tContext*variable) = let (request,context) = chaseType context request in match request with - + (* a function - must start out with a sequence of lambdas *) - | TCon("->",[argument;return_type]) -> begin + | TCon("->",[argument;return_type]) -> begin let newEnvironment = argument :: environment in match p with - | Abstraction(body) -> - likelihood context newEnvironment return_type body production + | Abstraction(body) -> + likelihood context newEnvironment return_type body production | _ -> (context, ~$ Float.neg_infinity) end - + | _ -> (* not a function so must be an application *) (* fragments we might match with based on their type *) let candidates = unifying_fragments production environment request context in - + (* The candidates are all different things that we could have possibly used *) - + (* For each way of carving up the program into a function and a list of arguments... *) - possible_application_parses p |> List.map ~f:(fun (f,arguments) -> + possible_application_parses p |> List.map ~f:(fun (f,arguments) -> List.map candidates ~f:(fun (candidate_index,candidate,unified_type,context,ll) -> try let (context, fragment_type, holes, bindings) = match f with | Index(i) -> if FIndex(i) = candidate then (context, List.nth_exn environment i, [], FreeMap.empty) else raise FragmentFail - | _ -> + | _ -> bind_fragment context environment candidate f in (* Printf.printf "BOUND: %s & %s\n" (string_of_program f) (string_of_fragment candidate); *) @@ -113,7 +113,7 @@ let likelihood_under_sfg (g : sfg) (request : tp) (expression : program) : varia pad_type_with_arguments context (List.length arguments) request in let context = unify context fragment_request fragment_type in let (fragment_type, context) = chaseType context fragment_type in - + let (argument_types, _) = arguments_and_return_of_type fragment_type in if not (List.length argument_types = List.length arguments) then begin @@ -132,13 +132,13 @@ let likelihood_under_sfg (g : sfg) (request : tp) (expression : program) : varia (* treat the holes and the bindings as though they were arguments *) let arguments = List.map holes ~f:(fun (_,h) -> h) @ - List.map (FreeMap.to_alist bindings) ~f:(fun (_,(_,binding)) -> binding) @ + List.map (FreeMap.to_alist bindings) ~f:(fun (_,(_,binding)) -> binding) @ arguments in let argument_types = List.map holes ~f:(fun (ht,_) -> ht) @ - List.map (FreeMap.to_alist bindings) ~f:(fun (_,(binding,_)) -> binding) @ + List.map (FreeMap.to_alist bindings) ~f:(fun (_,(binding,_)) -> binding) @ argument_types in - let (application_likelihood, context) = + let (application_likelihood, context) = List.fold_right (List.zip_exn arguments argument_types) ~init:(ll,context) ~f:(fun (argument, argument_type) (ll,context) -> @@ -159,8 +159,8 @@ let likelihood_under_sfg (g : sfg) (request : tp) (expression : program) : varia (oldContext,acc) end | Some(c) when is_valid (ll.data |> get_some) -> (c, log_soft_max [acc; ll]) | Some(_) -> (oldContext, acc)) - - + + in likelihood empty_context [] request expression 0 |> snd @@ -174,5 +174,5 @@ let estimate_categorized_fragment_grammar (fg : fragment_grammar) (frontiers : f |> fold1 (+&) in let parameters = g.logVariables @ (g.productionProbabilities |> List.map ~f:(List.map ~f:(fun (_,_,q) -> q)) |> List.concat) in - ignore(gradient_descent (~$0. -& joint) parameters); + ignore(gradient_descent (~$0. -& joint) parameters : unit); Printf.printf "%s\n" (string_of_categorized_grammar g); diff --git a/solvers/solver.ml b/solvers/solver.ml index ca332835d..53f2ff847 100644 --- a/solvers/solver.ml +++ b/solvers/solver.ml @@ -1,19 +1,18 @@ open Core -open Physics -open Pregex -open Tower +open [@warning "-33"] Physics +open [@warning "-33"] Pregex +open [@warning "-33"] Tower (* open Vs *) -open Differentiation -open TikZ +open [@warning "-33"] Differentiation +open [@warning "-33"] TikZ open Utils open Type -open Program +open [@warning "-33"] Program open Enumeration open Task open Grammar -open Task -open FastType +open [@warning "-33"] FastType let load_problems channel = let open Yojson.Basic.Util in @@ -56,9 +55,9 @@ let load_problems channel = with _ -> raise (Failure "could not unpack") in - let tf = j |> member "tasks" |> to_list |> List.map ~f:(fun j -> + let tf = j |> member "tasks" |> to_list |> List.map ~f:(fun j -> let e = j |> member "examples" |> to_list in - let task_type = j |> member "request" |> deserialize_type in + let task_type = j |> member "request" |> deserialize_type in let examples = e |> List.map ~f:(fun ex -> (ex |> member "inputs" |> to_list |> List.map ~f:unpack, ex |> member "output" |> unpack)) in let maximum_frontier = j |> member "maximumFrontier" |> to_int in @@ -72,7 +71,7 @@ let load_problems channel = | None -> (Printf.eprintf " (ocaml) FATAL: Could not find handler for %s\n" special; exit 1) with _ -> supervised_task) ~timeout:timeout name task_type examples - in + in (task, maximum_frontier)) in @@ -80,11 +79,11 @@ let load_problems channel = (* let most_specific_type = unify_many_types (tf |> List.map ~f:(fun (t,_) -> t.task_type)) in * let tf = tf |> List.map ~f:(fun (t,f) -> ({t with task_type=most_specific_type},f)) in *) - let verbose = try j |> member "verbose" |> to_bool + let verbose = try j |> member "verbose" |> to_bool with _ -> false in - - let _ = try + + let _ : unit = try shatter_factor := (j |> member "shatter" |> to_int) with _ -> () in @@ -108,7 +107,7 @@ let load_problems channel = let timeout = j |> member "timeout" |> to_number in let nc = try - j |> member "nc" |> to_int + j |> member "nc" |> to_int with _ -> 1 in (tf,g, @@ -117,9 +116,8 @@ let load_problems channel = nc,timeout,verbose) let export_frontiers number_enumerated tf solutions : string = - let open Yojson.Basic.Util in let open Yojson.Basic in - let serialization : Yojson.Basic.json = + let serialization : Yojson.Basic.t = `Assoc(("number_enumerated",`Int(number_enumerated)) :: List.map2_exn tf solutions ~f:(fun (t,_) ss -> (t.name, `List(ss |> List.map ~f:(fun s -> @@ -131,13 +129,13 @@ let export_frontiers number_enumerated tf solutions : string = ;; -let _ = +let _ :unit = let (tf,g, lowerBound,upperBound,budgetIncrement, mfp, nc,timeout, verbose) = - load_problems Pervasives.stdin in + load_problems Stdlib.stdin in let solutions, number_enumerated = enumerate_for_tasks ~maxFreeParameters:mfp ~lowerBound:lowerBound ~upperBound:upperBound ~budgetIncrement:budgetIncrement ~verbose:verbose ~nc:nc ~timeout:timeout g tf diff --git a/solvers/string_transformation.ml b/solvers/string_transformation.ml index 07f71a7fd..9053f70bb 100644 --- a/solvers/string_transformation.ml +++ b/solvers/string_transformation.ml @@ -1,7 +1,7 @@ open Core.Std open Re2 - + open Utils open Type open Program @@ -9,7 +9,7 @@ open Enumeration open Task open Grammar open EC - + let load_tasks f = let open Yojson.Basic.Util in let j = Yojson.Basic.from_file f in @@ -17,7 +17,7 @@ let load_tasks f = (* Printf.printf "%s\n" (Yojson.Basic.pretty_to_string t); *) let name = t |> member "name" |> to_string in let ex = - (t |> member "train" |> to_list)@(t |> member "test" |> to_list) |> + (t |> member "train" |> to_list)@(t |> member "test" |> to_list) |> List.map ~f:(fun example -> let x = example |> member "i" |> to_string in let y = example |> member "o" |> to_string in @@ -55,7 +55,7 @@ let primitive_find_string = primitive "find-string" (tstring @> tstring @> tint) String.index target (pattern.[0]) |> get_some);; let primitive_replace = primitive "string-replace" (tstring @> tstring @> tstring @> tstring) (fun x y s -> - if String.length x = 0 then raise (Failure "Replacing empty string") else + if String.length x = 0 then raise (Failure "Replacing empty string") else let rec loop s = if String.length s = 0 then s else if String.is_prefix s ~prefix:x then @@ -70,11 +70,11 @@ let primitive_string_join = primitive "join" (tstring @> tlist tstring @> tstrin -let _ = +let _ : unit = let n = "stringTransformation.json" in let n = "syntheticString.json" in let tasks = load_tasks n in - + let g = primitive_grammar ([ primitive0; (* primitive1; primitive_n1; *) primitive_increment; primitive_decrement; primitive_emptyString; @@ -104,4 +104,3 @@ let _ = ~alpha:4. ~keepTheBest:1 ~arity:2 10000 5 (* (lambda (map-string $0 (lambda (slice-string (-1 k0) k0 $0)) $0)) *) - diff --git a/solvers/task.ml b/solvers/task.ml index 9eee15b3c..0af918c3a 100644 --- a/solvers/task.ml +++ b/solvers/task.ml @@ -1,5 +1,4 @@ open Core -open Unix open CachingTable open Timeout @@ -27,7 +26,7 @@ let gen_passwd length = | n when n < 26 + 26 -> int_of_char 'A' + n - 26 | n -> int_of_char '0' + n - 26 - 26 in let gen _ = String.make 1 (char_of_int(gen())) in - String.concat (Array.to_list (Array.init length gen)) + String.concat (Array.to_list (Array.init length ~f:gen)) let supervised_task ?timeout:(timeout = 0.001) name ty examples = @@ -42,7 +41,7 @@ let supervised_task ?timeout:(timeout = 0.001) name ty examples = try match run_for_interval timeout - (fun () -> run_lazy_analyzed_with_arguments p xs = y) + (fun () -> Core.Poly.equal (run_lazy_analyzed_with_arguments p xs) y) with | Some(true) -> loop e | _ -> false @@ -62,7 +61,7 @@ let supervised_task ?timeout:(timeout = 0.001) name ty examples = } let task_handler = Hashtbl.Poly.create();; -let register_special_task name handler = Hashtbl.set task_handler name handler;; +let register_special_task name handler = Hashtbl.set task_handler ~key:name ~data:handler;; let recent_logo_program : (program*((((int, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t)*float) option)) option ref = ref None;; let run_recent_logo ~timeout program = @@ -75,10 +74,10 @@ let run_recent_logo ~timeout program = let x = run_lazy_analyzed_with_arguments p [] in let l = LogoLib.LogoInterpreter.turtle_to_list x in if not (LogoLib.LogoInterpreter.logo_contained_in_canvas l) - then None + then None else match CachingTable.find p2i l with | Some(bx) -> Some(bx) - | None -> + | None -> let bx = LogoLib.LogoInterpreter.turtle_to_array_and_cost x 28 in CachingTable.set p2i l bx; Some(bx)) @@ -92,7 +91,7 @@ let run_recent_logo ~timeout program = ;; - +let _ : unit = register_special_task "LOGO" (fun extras ?timeout:(timeout = 0.001) name ty examples -> let open Yojson.Basic.Util in @@ -100,7 +99,7 @@ register_special_task "LOGO" (fun extras ?timeout:(timeout = 0.001) name ty exam try extras |> member "costMatters" |> to_bool with _ -> assert false - in + in let by = match examples with | [([0],y)] -> @@ -126,7 +125,7 @@ register_special_task "LOGO" (fun extras ?timeout:(timeout = 0.001) name ty exam | UnknownPrimitive(n) -> raise (Failure ("Unknown primitive: "^n)) | EnumerationTimeout -> raise EnumerationTimeout | _ -> log 0.0) - });; + }); register_special_task "differentiable" @@ -144,7 +143,7 @@ register_special_task "differentiable" try extras |> member name |> to_int with _ -> default - in + in let temperature = maybe_float "temperature" 1. in let parameterPenalty = maybe_float "parameterPenalty" 0. in let maxParameters = maybe_int "maxParameters" 99 in @@ -161,15 +160,15 @@ register_special_task "differentiable" extras |> member "proportional" |> to_bool with _ -> false in - - + + (* Process the examples and wrap them inside of placeholders *) let (argument_types, return_type) = arguments_and_return_of_type ty in let examples = examples |> List.map ~f:(fun (xs,y) -> (List.map2_exn argument_types xs ~f:placeholder_data, placeholder_data return_type y)) in - + let loss = polymorphic_sse ~clipOutput ~clipLoss return_type in { name = name ; task_type = ty ; @@ -177,7 +176,7 @@ register_special_task "differentiable" (fun expression -> let (p,parameters) = replace_placeholders expression in assert (List.length parameters <= maxParameters); - if List.length parameters > maxParameters || List.length parameters > actualParameters then log 0. else + if List.length parameters > maxParameters || List.length parameters > actualParameters then log 0. else let p = analyze_lazy_evaluation p in (* let predictions = examples |> List.map ~f:(fun (xs,_) -> *) (* run_for_interval timeout (fun () -> run_lazy_analyzed_with_arguments p xs)) *) @@ -208,11 +207,11 @@ register_special_task "differentiable" | Some(l) -> let n = List.length examples |> Int.to_float in let d = List.length parameters |> Int.to_float in - let l = if proportional && List.length parameters > 0 then begin + let l = if proportional && List.length parameters > 0 then begin assert (List.length parameters = 1); parameters |> List.iter ~f:(fun p -> update_variable p 1.); assert (false) - end else + end else let l = l *& (~$ (1. /. n)) in let l = restarting_optimize (rprop ~lr ~decay ~grow) ~attempts:restarts @@ -221,11 +220,12 @@ register_special_task "differentiable" parameters l in l in + let open Float in match lossThreshold with | None -> 0. -. d*.parameterPenalty -. n *. l /. temperature | Some(t) -> if l < t then 0. -. d*.parameterPenalty else log 0.) - });; + }); register_special_task "stringConstant" (fun extras (* ?parameterPenalty:(parameterPenalty=0.) *) @@ -237,7 +237,7 @@ register_special_task "stringConstant" (fun extras try extras |> member name |> to_int with _ -> default - in + in let stringConstants = extras |> member "stringConstants" |> to_list |> List.map ~f:to_string |> List.map ~f:(String.to_list) in @@ -246,7 +246,7 @@ register_special_task "stringConstant" (fun extras let lc = log (26.*.2.+.10.) in let lc = 0.-.lc in - + { name = name ; task_type = ty ; log_likelihood = @@ -261,26 +261,25 @@ register_special_task "stringConstant" (fun extras try (match run_for_interval timeout - (fun () -> run_lazy_analyzed_with_arguments p' xs = y) + (fun () -> Core.Poly.equal (run_lazy_analyzed_with_arguments p' xs) y) with | Some(true) -> loop e | _ -> false) with | UnknownPrimitive(n) -> raise (Failure ("Unknown primitive: "^n)) - | otherException -> begin - if otherException = EnumerationTimeout then raise EnumerationTimeout else false - end + | EnumerationTimeout -> raise EnumerationTimeout + | _ -> false in let hit = loop examples in if hit then lc*.(Float.of_int (string_constants_length p)) - else log 0.) |> List.fold_right ~init:(log 0.) ~f:max) + else log 0.) |> List.fold_right ~init:(log 0.) ~f:Float.max) });; let keep_best_programs_in_frontier (k : int) (f : frontier) : frontier = {request = f.request; - programs = List.sort ~compare:(fun (_,a) (_,b) -> if a > b then -1 else 1) f.programs |> flip List.take k } + programs = List.sort ~compare:(fun (_,a) (_,b) -> Float.compare b a) f.programs |> flip List.take k } (* Takes a frontier and a task. Ads in the likelihood on the task to the frontier and removes things that didn't hit the task *) @@ -288,7 +287,8 @@ let score_programs_for_task (f:frontier) (t:task) : frontier = {request = f.request; programs = f.programs |> List.filter_map ~f:(fun (program, descriptionLength) -> let likelihood = t.log_likelihood program in - if likelihood > -0.1 then + let open Float in + if likelihood > -0.1 then Some((program, descriptionLength +. likelihood)) else None) } @@ -297,6 +297,7 @@ type hit_result = {hit_program: string; hit_likelihood: float; hit_prior: float; hit_time: float;} +[@@deriving equal] let enumerate_for_tasks (g: contextual_grammar) ?verbose:(verbose = true) ~maxFreeParameters @@ -318,17 +319,17 @@ let enumerate_for_tasks (g: contextual_grammar) ?verbose:(verbose = true) let tasks = Array.of_list (tf |> List.map ~f:fst) in let request = tasks.(0).task_type in - assert (Array.for_all tasks ~f:(fun t -> t.task_type = request)); + assert (Array.for_all tasks ~f:(fun t -> equal_tp t.task_type request)); (* Store the hits in a priority queue *) (* We will only ever maintain maximumFrontier best solutions *) let hits = - Array.init nt ~f:(fun _ -> + Array.init nt ~f:(fun _ -> Heap.create ~cmp:(fun h1 h2 -> Float.compare (h1.hit_likelihood+.h1.hit_prior) (h2.hit_likelihood+.h2.hit_prior)) ()) in - + let lower_bound = ref lowerBound in let startTime = Time.now () in @@ -337,7 +338,7 @@ let enumerate_for_tasks (g: contextual_grammar) ?verbose:(verbose = true) while not (enumeration_timed_out()) && List.exists (range nt) ~f:(fun j -> Heap.length hits.(j) < maximumFrontier.(j)) - && !lower_bound +. budgetIncrement <= upperBound + && Float.(<=) (!lower_bound +. budgetIncrement) upperBound do let number_of_enumerated_programs = ref 0 in let final_results = @@ -352,13 +353,13 @@ let enumerate_for_tasks (g: contextual_grammar) ?verbose:(verbose = true) (fun p logPrior -> incr number_of_enumerated_programs; incr total_number_of_enumerated_programs; - + let mdl = 0.-.logPrior in - assert( !lower_bound <= mdl); - assert( mdl < budgetIncrement+.(!lower_bound)); + assert(Float.(<=) !lower_bound mdl); + assert(Float.(<) mdl (budgetIncrement+.(!lower_bound))); - range nt |> List.iter ~f:(fun j -> + range nt |> List.iter ~f:(fun j -> let logLikelihood = tasks.(j).log_likelihood p in if is_valid logLikelihood then begin let dt = Time.abs_diff startTime (Time.now ()) @@ -386,16 +387,15 @@ let enumerate_for_tasks (g: contextual_grammar) ?verbose:(verbose = true) let new_heap = array_of_heaps.(j) in let old_heap = hits.(j) in List.iter new_heap ~f:(fun element -> - if not (Heap.mem old_heap ~equal:(=) element) then + if not (Heap.mem old_heap ~equal:equal_hit_result element) then (Heap.add old_heap element; if Heap.length old_heap > maximumFrontier.(j) then Heap.remove_top old_heap)))) ; - + lower_bound := budgetIncrement+. (!lower_bound); done ; - + (hits |> Array.to_list |> List.map ~f:Heap.to_list, !total_number_of_enumerated_programs) - diff --git a/solvers/timeout.ml b/solvers/timeout.ml index d14bb4bf3..9a07b2c1f 100644 --- a/solvers/timeout.ml +++ b/solvers/timeout.ml @@ -12,21 +12,21 @@ let run_for_interval' (time : float) (c : unit -> 'a) : 'a option = let reset_sigalrm () = Sys.set_signal Sys.sigalrm old_behavior in try - ignore (Unix.setitimer ITIMER_REAL {it_interval = 0.0; it_value = time}) ; + ignore (Unix.setitimer ITIMER_REAL {it_interval = 0.0; it_value = time}: Unix.interval_timer_status) ; let res = c () in - ignore (Unix.setitimer ITIMER_REAL {it_interval = 0.0; it_value = 0.0}) ; + ignore (Unix.setitimer ITIMER_REAL {it_interval = 0.0; it_value = 0.0}: Unix.interval_timer_status) ; reset_sigalrm () ; Some(res) with | Timeout -> begin - ignore (Unix.setitimer ITIMER_REAL {it_interval = 0.0; it_value = 0.0}) ; + ignore (Unix.setitimer ITIMER_REAL {it_interval = 0.0; it_value = 0.0}: Unix.interval_timer_status) ; reset_sigalrm () ; None end | e -> begin - ignore (Unix.setitimer ITIMER_REAL {it_interval = 0.0; it_value = 0.0}) ; + ignore (Unix.setitimer ITIMER_REAL {it_interval = 0.0; it_value = 0.0}: Unix.interval_timer_status) ; reset_sigalrm () ; raise e end @@ -38,7 +38,7 @@ let run_for_interval' (time : float) (c : unit -> 'a) : 'a option = (* and ocaml, the wonderful language it is, does not allow you to temporarily disable the garbage collector *) (* So this version of run_for_interval allows you to repeatedly try to run the thing for the interval *) let rec run_for_interval ?attempts:(attempts=1) dt c = - if attempts < 1 then None else + if attempts < 1 then None else match run_for_interval' dt c with | Some(v) -> Some(v) | None -> run_for_interval ~attempts:(attempts - 1) dt c diff --git a/solvers/tower.ml b/solvers/tower.ml index f6a2fa7e2..45693b472 100644 --- a/solvers/tower.ml +++ b/solvers/tower.ml @@ -1,6 +1,5 @@ open Core -open Client open Timeout open Task open Utils @@ -12,7 +11,7 @@ type tower_state = {hand_position : int; let empty_tower_state = {hand_position = 0; hand_orientation = 1;} - + (* ttower = state -> (state, list of blocks) *) type tt = tower_state -> tower_state * ( (int*int*int) list) @@ -48,16 +47,17 @@ let block w h = let (hand', rest) = k hand in (hand', (xOffset + hand.hand_position, w, h) :: rest) in - ignore(primitive n (ttower @> ttower) v) + ignore(primitive n (ttower @> ttower) v : program) ;; -block 3 1;; -block 1 3;; -block 1 1;; -block 2 1;; -block 1 2;; -block 4 1;; -block 1 4;; +let _ : unit = +block 3 1; +block 1 3; +block 1 1; +block 2 1; +block 1 2; +block 4 1; +block 1 4; ignore(primitive "left" (tint @> ttower @> ttower) (let f : int -> tt -> tt = fun (d : int) -> @@ -66,7 +66,7 @@ ignore(primitive "left" (tint @> ttower @> ttower) let hand' = {hand with hand_position = hand.hand_position - d} in let (hand'', rest) = k hand' in (hand'', rest) - in f));; + in f): program); ignore(primitive "right" (tint @> ttower @> ttower) (let f : int -> tt -> tt = fun (d : int) -> fun (k : tt) -> @@ -74,34 +74,34 @@ ignore(primitive "right" (tint @> ttower @> ttower) let hand' = {hand with hand_position = hand.hand_position + d} in let (hand'', rest) = k hand' in (hand'', rest) - in f));; + in f): program); ignore(primitive "tower_loop" (tint @> (tint @> ttower) @> ttower @> ttower) - (let rec f (start : int) (stop : int) (body : int -> tt) : tt = fun (hand : tower_state) -> + (let rec f (start : int) (stop : int) (body : int -> tt) : tt = fun (hand : tower_state) -> if start >= stop then (hand,[]) else let (hand', thisIteration) = body start hand in let (hand'', laterIterations) = f (start+1) stop body hand' in (hand'', thisIteration @ laterIterations) - in fun (n : int) (b : int -> tt) (k : tt) : tt -> fun (hand : tower_state) -> + in fun (n : int) (b : int -> tt) (k : tt) : tt -> fun (hand : tower_state) -> let (hand, body_blocks) = f 0 n b hand in let hand, later_blocks = k hand in - (hand, body_blocks @ later_blocks)));; + (hand, body_blocks @ later_blocks)): program); ignore(primitive "tower_loopM" (tint @> (tint @> ttower @> ttower) @> ttower @> ttower) - (fun i (f : int -> tt -> tt) (z : tt) : tt -> List.fold_right (0 -- (i-1)) ~f ~init:z));; + (fun i (f : int -> tt -> tt) (z : tt) : tt -> List.fold_right (0 -- (i-1)) ~f ~init:z): program); ignore(primitive "tower_embed" ((ttower @> ttower) @> ttower @> ttower) (fun (body : tt -> tt) (k : tt) : tt -> fun (hand : tower_state) -> let (_, bodyActions) = body empty_tower hand in let (hand', laterActions) = k hand in - (hand', bodyActions @ laterActions)));; + (hand', bodyActions @ laterActions)): program); ignore(primitive "moveHand" (tint @> ttower @> ttower) (fun (d : int) (k : tt) : tt -> fun (state : tower_state) -> - k {state with hand_position = state.hand_position + state.hand_orientation*d}));; + k {state with hand_position = state.hand_position + state.hand_orientation*d}): program); ignore(primitive "reverseHand" (ttower @> ttower) (fun (k : tt) : tt -> fun (state : tower_state) -> - k {state with hand_orientation = -1*state.hand_orientation}));; - + k {state with hand_orientation = -1*state.hand_orientation}): program);; + let simulate_without_physics plan = let overlaps (x,w,h) (x',y',w',h') = @@ -114,7 +114,7 @@ let simulate_without_physics plan = in let lowest_possible_height (_,_,h) = h/2 in - let place_at_height (x,w,h) y = (x,y,w,h) in + let place_at_height (x,w,h) y = (x,y,w,h) in let place_block world block = let lowest = List.filter_map world ~f:(overlaps block) |> @@ -127,23 +127,21 @@ let simulate_without_physics plan = | [] -> world | b :: bs -> run bs (place_block world b) in - let simulated = run plan [] |> List.sort ~compare:(fun x y -> - if x > y then 1 else if x < y then -1 else 0 - ) in + let simulated = run plan [] |> List.sort ~compare:[%compare: int * int * int * int] in simulated ;; let blocks_extent blocks = - if blocks = [] then 0 else + if List.is_empty blocks then 0 else let xs = blocks |> List.map ~f:(fun (x,_,_,_) -> x) in let x1 = List.fold_left ~init:(List.hd_exn xs) ~f:max xs in let x0 = List.fold_left ~init:(List.hd_exn xs) ~f:min xs in x1 - x0 let tower_height blocks = - if blocks = [] then 0 else + if List.is_empty blocks then 0 else let ys = blocks |> List.map ~f:(fun (_,y,_,h) -> y + h/2) in - let y1 = List.fold_left ~init:(List.hd_exn ys) ~f:max ys in + let y1 = List.fold_left ~init:(List.hd_exn ys) ~f:max ys in let ys = blocks |> List.map ~f:(fun (_,y,_,h) -> y - h/2) in let y0 = List.fold_left ~init:(List.hd_exn ys) ~f:min ys in y1 - y0 @@ -164,9 +162,9 @@ let evaluate_discrete_tower_program timeout p = recent_tower := Some(p); (* Printf.eprintf "%s\n" (string_of_program p); *) let p = analyze_lazy_evaluation p in - let new_discrete = + let new_discrete = try - match run_for_interval + [@warning "-20"] match run_for_interval timeout (fun () -> run_lazy_analyzed_with_arguments p [fun s -> (s, [])] empty_tower_state |> snd) with @@ -180,22 +178,22 @@ let evaluate_discrete_tower_program timeout p = (* we have to be a bit careful with exceptions *) (* if the synthesized program generated an exception, then we just terminate w/ false *) (* but if the enumeration timeout was triggered during program evaluation, we need to pass the exception on *) - | otherException -> begin - if otherException = EnumerationTimeout then raise EnumerationTimeout else [] - end + | EnumerationTimeout -> raise EnumerationTimeout + | _ -> [] in recent_discrete := new_discrete; new_discrete end ;; +let _ : unit = register_special_task "supervisedTower" (fun extra ?timeout:(timeout = 0.001) - name task_type examples -> - assert (task_type = ttower @> ttower); - assert (examples = []); + name task_type examples -> + assert (equal_tp task_type (ttower @> ttower)); + assert (List.is_empty examples); let open Yojson.Basic.Util in - + let plan = extra |> member "plan" |> to_list |> List.map ~f:(fun command -> match command |> to_list with | [a;b;c;] -> (a |> to_int, b |> to_int, c |> to_int) @@ -208,9 +206,8 @@ register_special_task "supervisedTower" (fun extra ?timeout:(timeout = 0.001) task_type = task_type ; log_likelihood = (fun p -> - let hit = evaluate_discrete_tower_program timeout p = plan in + let hit = [%equal: (int * int * int * int) list] (evaluate_discrete_tower_program timeout p) plan in (* Printf.eprintf "\t%b\n\n" hit; *) if hit then 0. else log 0.) }) ;; - diff --git a/solvers/type.ml b/solvers/type.ml index 9239b36c5..3bbdea6c1 100644 --- a/solvers/type.ml +++ b/solvers/type.ml @@ -1,10 +1,10 @@ open Core -open Funarray -type tp = +type tp = | TID of int | TCon of string * tp list * bool - +[@@deriving equal] + let is_polymorphic = function | TID(_) -> true @@ -14,7 +14,7 @@ let rec tp_eq a b = match (a,b) with | (TID(x),TID(y)) -> x = y | (TCon(k1,as1,_),TCon(k2,as2,_)) -> - k1 = k2 && (type_arguments_equal as1 as2) + String.(=) k1 k2 && (type_arguments_equal as1 as2) | _ -> false and type_arguments_equal xs ys = match (xs,ys) with @@ -47,7 +47,7 @@ let rec arguments_and_return_of_type t = (* return_of_type (t1 @> t2 @> ... @> T) = T *) let rec return_of_type t = match t with - | TCon("->",[_;q],_) -> return_of_type q + | TCon("->",[_;q],_) -> return_of_type q | _ -> t (* arguments_of_type (t1 @> t2 @> ... @> T) = [t1;t2;...] *) @@ -67,7 +67,8 @@ let left_of_arrow t = | _ -> raise (Failure "right_of_arrow") -let rec show_type (is_return : bool) (t : tp) : string = +let rec show_type (is_return : bool) (t : tp) : string = + let open String in match t with | TID(i) -> "t"^string_of_int i | TCon(k,[],_) -> k @@ -77,16 +78,16 @@ let rec show_type (is_return : bool) (t : tp) : string = else "("^(show_type false p)^" -> "^(show_type true q)^")" | TCon(k,a,_) -> k^"("^(String.concat ~sep:", " (List.map a ~f:(show_type true)))^")" - + let string_of_type = show_type true -let makeTID (next, substitution) = +let makeTID (next, substitution) = (TID(next), (next + 1, Funarray.cons None substitution)) let rec makeTIDs (n : int) (k : tContext) : tContext = if n = 0 then k else makeTIDs (n-1) (makeTID k |> snd) -let bindTID i t (next, bindings) : tContext = +let bindTID i t (next, bindings) : tContext = (next, Funarray.update bindings (next - i - 1) (Some(t))) let lookupTID (next, bindings) j = @@ -111,7 +112,7 @@ let lookupTID (next, bindings) j = (* | None -> (t,context) *) let rec applyContext k t = - if not (is_polymorphic t) then (k,t) else + if not (is_polymorphic t) then (k,t) else match t with | TCon(c,xs,_) -> let (k,xs) = List.fold_right xs ~init:(k,[]) ~f:(fun x (k,xs) -> @@ -129,20 +130,21 @@ let rec applyContext k t = let rec occurs (i : int) (t : tp) : bool = - if not (is_polymorphic t) then false else + if not (is_polymorphic t) then false else match t with | TID(j) -> j = i - | TCon(_,ts,_) -> - List.exists ts (occurs i) + | TCon(_,ts,_) -> + List.exists ts ~f:(occurs i) let occursCheck = true exception UnificationFailure -let rec might_unify t1 t2 = +let rec might_unify t1 t2 = + let open String in match (t1, t2) with - | (TCon(k1,as1,_), TCon(k2,as2,_)) when k1 = k2 -> - List.for_all2_exn as1 as2 might_unify + | (TCon(k1,as1,_), TCon(k2,as2,_)) when k1 = k2 -> + List.for_all2_exn as1 as2 ~f:might_unify | (TID(_),_) -> true | (_,TID(_)) -> true | _ -> false @@ -154,27 +156,27 @@ let rec unify context t1 t2 : tContext = then begin if tp_eq t1 t2 then context else raise UnificationFailure end - else + else match (t1,t2) with | (TID(j),t) -> - if tp_eq t1 t2 then context + if tp_eq t1 t2 then context else (if occurs j t then raise UnificationFailure else bindTID j t context) | (t,TID(j)) -> - if t1 = t2 then context + if equal_tp t1 t2 then context else (if occurs j t then raise UnificationFailure else bindTID j t context) - | (TCon(k1,as1,_),TCon(k2,as2,_)) when k1 = k2 -> + | (TCon(k1,as1,_),TCon(k2,as2,_)) when String.(=) k1 k2 -> List.fold2_exn ~init:context as1 as2 ~f:unify | _ -> raise UnificationFailure -let instantiate_type k t = +let instantiate_type k t = let substitution = ref [] in let k = ref k in let rec instantiate j = - if not (is_polymorphic j) then j else + if not (is_polymorphic j) then j else match j with | TID(i) -> (try List.Assoc.find_exn ~equal:(fun a b -> a = b) !substitution i - with Not_found-> + with Not_found_s _ -> let (t,k') = makeTID !k in k := k'; substitution := (i,t)::!substitution; @@ -193,28 +195,28 @@ let instantiate_type' context_reference t = let new_context, t' = instantiate_type !context_reference t in context_reference := new_context; t' - + (* puts a type into normal form *) -let canonical_type t = +let canonical_type t = let next = ref 0 in let substitution = ref [] in - let rec canon q = + let rec canon q = match q with | TID(i) -> (try TID(List.Assoc.find_exn ~equal:(=) !substitution i) - with Not_found -> + with Not_found_s _ -> substitution := (i,!next)::!substitution; next := (1+ !next); TID(!next-1)) | TCon(k,a,_) -> kind k (List.map ~f:canon a) in canon t -let rec next_type_variable t = +let rec next_type_variable t = match t with | TID(i) -> i+1 | TCon(_,[],_) -> 0 - | TCon(_,is,_) -> List.fold_left ~f:max ~init:0 (List.map is next_type_variable) + | TCon(_,is,_) -> List.fold_left ~f:max ~init:0 (List.map is ~f:next_type_variable) (* tries to instantiate a universally quantified type with a given request *) -(* let instantiated_type universal_type requested_type = +(* let instantiated_type universal_type requested_type = * try * let (universal_type,c) = instantiate_type empty_context universal_type in * let (requested_type,c) = instantiate_type c requested_type in @@ -226,12 +228,12 @@ let rec next_type_variable t = * let t = canonical_type t in * let (xs,r) = arguments_and_return_of_type t in * let free_variables = next_type_variable in - * - * + * + * * fun (target, context) -> * if not (might_unify target r) then raise UnificationFailure else * let bindings = Array.make free_variables None in - * + * * let rec u k template original = * match (template, original) with * | (TID(templateVariable), v) -> begin @@ -246,7 +248,9 @@ let rec next_type_variable t = -let rec get_arity = function +let rec get_arity t = + let open String in + match t with | TCon(a,[_;r],_) when a = "->" -> 1+get_arity r | _ -> 0 @@ -291,7 +295,7 @@ let unify_many_types ts = let (k',t') = instantiate_type !k t' in k := unify k' t' t); applyContext !k t |> snd - + let rec deserialize_type j = let open Yojson.Basic.Util in @@ -305,8 +309,7 @@ let rec deserialize_type j = let rec serialize_type t = - let open Yojson.Basic in - let j : json = + let j : Yojson.Basic.t = match t with | TID(i) -> `Assoc(["index",`Int(i)]) | TCon(k,a,_) -> diff --git a/solvers/utils.ml b/solvers/utils.ml index 9184be469..af7bdfe8e 100644 --- a/solvers/utils.ml +++ b/solvers/utils.ml @@ -1,7 +1,4 @@ open Core -open Unix.Select_fds -open Sys -open Obj let power_of exponent natural = let rec loop n = @@ -9,7 +6,7 @@ let power_of exponent natural = if n > natural then false else loop (n*exponent) in loop 1 - + let singleton_head = function | [x] -> x @@ -21,8 +18,8 @@ let float_of_bool = function | true -> 1. | false -> 0. -let round f = floor (f+.0.5) - +let round f = Float.round_down (f+.0.5) + let join ?separator:(separator = " ") elements= String.concat ~sep:separator elements (* let rec replicate (n : int) (x : 'a) : 'a list = *) @@ -71,29 +68,30 @@ let sum = List.fold_left ~f:(+) ~init:0 let minimum l = List.reduce_exn l ~f:min ;; -let minimum_by f l = List.reduce_exn l ~f:(fun x y -> if f x < f y then x else y) -;; -let maximum_by f l = List.reduce_exn l ~f:(fun x y -> if f x > f y then x else y) +let minimum_by f l = List.reduce_exn l ~f:(fun x y -> if Float.(<) (f x) (f y) then x else y) ;; +(* let maximum_by f l = List.reduce_exn l ~f:(fun x y -> if f x > f y then x else y) *) +(* ;; *) let sort_by f l = List.sort ~compare:(fun x y -> let x = f x in let y = f y in + let open Float in if x = y then 0 else if x > y then 1 else -1) l -let memorize f = +let memorize f = let table = Hashtbl.Poly.create () in - fun x -> + fun x -> match Hashtbl.Poly.find table x with | Some(y) -> y - | None -> + | None -> let y = f x in - ignore(Hashtbl.Poly.add table x y); + ignore(Hashtbl.Poly.add table ~key:x ~data:y : [ `Duplicate | `Ok ]); y -let maximum_by ~cmp l = - List.fold_left ~init:(List.hd_exn l) (List.tl_exn l) ~f:(fun a b -> +let maximum_by ~cmp l = + List.fold_left ~init:(List.hd_exn l) (List.tl_exn l) ~f:(fun a b -> if cmp a b > 0 then a else b) @@ -101,7 +99,7 @@ let rec map_list f = function | [] -> [f []] | (x :: xs) -> (f (x :: xs)) :: (map_list f xs) -let is_invalid (x : float) = x <> x || x = Float.infinity || x = Float.neg_infinity;; +let is_invalid (x : float) = let open Float in x <> x || x = Float.infinity || x = Float.neg_infinity;; let is_valid = compose not is_invalid;; let rec last_one = function @@ -109,14 +107,14 @@ let rec last_one = function | [x] -> x | _::y -> last_one y -let index_of l x = - let rec loop a r = +let index_of l x = + let rec loop a r = match r with [] -> raise (Failure "index_of: not found") | (y::ys) -> if y = x then a else loop (a+1) ys in loop 0 l -let set_equal c x y = +let set_equal c x y = let x = List.sort ~compare:c x and y = List.sort ~compare:c y in List.compare c x y = 0 @@ -124,7 +122,8 @@ let set_equal c x y = let log2 = log 2. -let lse x y = +let lse x y = + let open Float in if is_invalid x then y else if is_invalid y then x else if x > y then x +. log (1.0 +. exp (y-.x)) @@ -133,34 +132,35 @@ let lse x y = let softMax = lse -let lse_list (l : float list) : float = +let lse_list (l : float list) : float = List.fold_left l ~f:lse ~init:Float.neg_infinity (* log difference exponential: log(e^x - e^y) = x+log(1-e^(y-x)) *) -let lde x y = +let lde x y = + let open Float in assert(x >= y); x +. log (1. -. exp (y-.x)) -let rec remove_duplicates l = +let rec remove_duplicates l = match l with | [] -> [] | (x::y) -> x::(List.filter ~f:(fun z -> not (z = x)) (remove_duplicates y)) let merge_a_list ls ~f:c = let merged = Hashtbl.Poly.create () in - List.iter ls (fun l -> - List.iter l (fun (tag,value) -> + List.iter ls ~f:(fun l -> + List.iter l ~f:(fun (tag,value) -> try let old_value = Hashtbl.find_exn merged tag in Hashtbl.set merged ~key:tag ~data:(c value old_value) - with Not_found -> ignore (Hashtbl.add merged tag value) + with Not_found_s _ -> ignore (Hashtbl.add merged ~key:tag ~data:value : [ `Duplicate | `Ok ]) ) ); Hashtbl.to_alist merged -let combine_with f _ a b = +let combine_with f _ a b = match (a,b) with | (None,_) -> b | (_,None) -> a @@ -168,7 +168,7 @@ let combine_with f _ a b = let flip f x y = f y x -let (--) i j = +let (--) i j = let rec aux n acc = if n < i then acc else aux (n-1) (n :: acc) in aux j [] @@ -176,7 +176,8 @@ let (--) i j = let range n = 0 -- (n-1);; -let float_interval (i : float) (s : float) (j : float) : float list = +let float_interval (i : float) (s : float) (j : float) : float list = + let open Float in let rec aux n acc = if n < i then acc else aux (n-.s) (n :: acc) in aux j [] @@ -186,15 +187,15 @@ let float_interval (i : float) (s : float) (j : float) : float list = (* Core.Time. *) (* Core.Time.to_float @@ Time.now () *) let flush_everything () = - Pervasives.flush stdout; - Pervasives.flush stderr + Stdlib.flush stdout; + Stdlib.flush stderr -let time_it ?verbose:(verbose=true) description callback = +let time_it ?verbose:(verbose=true) description callback = let start_time = Time.now () in let return_value = callback () in - if verbose then begin - Printf.eprintf "%s in %s.\n" description (Time.diff (Time.now ()) start_time |> Time.Span.to_string); + if verbose then begin + Printf.eprintf "%s in %s.\n" description (Time.diff (Time.now ()) start_time |> Time.Span.to_string); flush_everything() end; return_value @@ -202,55 +203,53 @@ let time_it ?verbose:(verbose=true) description callback = let shuffle d = begin Random.self_init (); let nd = List.map ~f:(fun c -> (Random.bits (), c)) d in - let sond = List.sort compare nd in + let sond = List.sort ~compare:(fun a b -> compare (fst a) (fst b)) nd in List.map ~f:snd sond end (* progress bar *) type progress_bar = { maximum_progress : int; mutable current_progress : int; } -let make_progress_bar number_jobs = +let make_progress_bar number_jobs = { maximum_progress = number_jobs; current_progress = 0; } -let update_progress_bar bar new_progress = +let update_progress_bar bar new_progress = let max = Float.of_int bar.maximum_progress in let old_dots = Int.of_float @@ Float.of_int bar.current_progress *. 80.0 /. max in let new_dots = Int.of_float @@ Float.of_int new_progress *. 80.0 /. max in bar.current_progress <- new_progress; if new_dots > old_dots then let difference = min 80 (new_dots-old_dots) in - List.iter (1--difference) (fun _ -> Out_channel.output_char stdout '.'; Out_channel.flush stdout) - - + List.iter (1--difference) ~f:(fun _ -> Out_channel.output_char stdout '.'; Out_channel.flush stdout) let number_of_cores = ref 1;; (* number of CPUs *) let counted_CPUs = ref false;; (* have we counted the number of CPUs? *) -let cpu_count () = - try match Sys.os_type with - | "Win32" -> int_of_string (safe_get_some "CPU_count" @@ Sys.getenv "NUMBER_OF_PROCESSORS") +let cpu_count () = + try match Sys.os_type with + | "Win32" -> int_of_string (safe_get_some "CPU_count" @@ Sys.getenv "NUMBER_OF_PROCESSORS") | _ -> let i = Unix.open_process_in "getconf _NPROCESSORS_ONLN" in - let close () = ignore (Unix.close_process_in i) in + let close () = ignore (Unix.close_process_in i : Core.Unix.Exit_or_signal.t) in try Scanf.bscanf (Scanf.Scanning.from_channel i) "%d" (fun n -> close (); n) with e -> (close () ; raise e) with - | Not_found | Sys_error _ | Failure _ | Scanf.Scan_failure _ + | Not_found_s _ | Sys_error _ | Failure _ | Scanf.Scan_failure _ | End_of_file | Unix.Unix_error (_, _, _) -> 1 -let string_proper_prefix p s = - let rec loop n = +let string_proper_prefix p s = + let rec loop n = (n >= String.length p) || - (p.[n] = s.[n] && loop (n+1)) - in + (Char.(=) p.[n] s.[n] && loop (n+1)) + in String.length p < String.length s && loop 0 -let rec remove_index i l = +let rec remove_index i l = match (i,l) with | (0,x::xs) -> (x,xs) | (i,x::xs) -> let (j,ys) = remove_index (i-1) xs in @@ -259,12 +258,12 @@ let rec remove_index i l = let rec random_subset l = function | 0 -> l - | s -> + | s -> let i = Random.int (List.length l) in let (ith,r) = remove_index i l in ith :: (random_subset r (s-1)) -let avg l = +let avg l = List.fold_left ~init:0.0 ~f:(+.) l /. (Float.of_int @@ List.length l) let pi = 4.0 *. Float.atan 1.0 @@ -275,22 +274,25 @@ let normal s m = in s *. n +. m -let print_arguments () = - Array.iter Sys.argv ~f:(fun a -> Printf.printf "%s " a); +let print_arguments () = + Array.iter (Sys.get_argv ()) ~f:(fun a -> Printf.printf "%s " a); Out_channel.newline stdout (* samplers adapted from gsl *) -let rec uniform_positive () = +let rec uniform_positive () = + let open Float in let u = Random.float 1.0 in if u > 0.0 then u else uniform_positive () let uniform_interval ~l ~u = + let open Float in assert (u > l); let x = uniform_positive() in (l+.u)/.2. +. (u-.l)*.x -let rec sample_gamma a b = +let rec sample_gamma a b = + let open Float in if a < 1.0 then let u = uniform_positive () in @@ -298,8 +300,8 @@ let rec sample_gamma a b = else let d = a -. 1.0 /. 3.0 in let c = (1.0 /. 3.0) /. sqrt d in - let rec loop () = - let rec inner_loop () = + let rec loop () = + let rec inner_loop () = let x = normal 1.0 0.0 in let v = 1.0 +. c *. x in if v > 0.0 then (v,x) else inner_loop () @@ -308,13 +310,13 @@ let rec sample_gamma a b = let v = v*.v*.v in let u = uniform_positive () in if (u < 1.0 -. 0.0331 *. x *. x *. x *. x) || - (log u < 0.5 *. x *. x +. d *. (1.0 -. v +. log v)) + (log u < 0.5 *. x *. x +. d *. (1.0 -. v +. log v)) then b *. d *. v else loop () in loop () -let sample_uniform_dirichlet a n = +let sample_uniform_dirichlet a n = let ts = List.map (1--n) ~f:(fun _ -> sample_gamma a 1.0) in let norm = List.fold_left ~init:0.0 ~f:(+.) ts in List.map ts ~f:(fun t -> t/.norm) @@ -329,7 +331,7 @@ let sample_uniform_dirichlet a n = (* -let () = +let () = let a =2. in let b = 2. in let samples = List.map (1--1000) ~f:(fun _ -> let (x,y) =(sample_gamma a 1.0,sample_gamma b 1.0) in @@ -337,7 +339,7 @@ let () = let mean = (List.fold_left ~init:0.0 ~f:(+.) samples /. 1000.0) in let variance =List.fold_left ~init:0.0 ~f:(+.) (List.map samples ~f:(fun s -> (s-.mean)*.(s-.mean))) /. 1000.0 in - Printf.printf "mean: %f\n" mean; + Printf.printf "mean: %f\n" mean; Printf.printf "variance: %f\n" variance;; *) @@ -347,10 +349,10 @@ let command_output cmd = let buf = Buffer.create 16 in (try while true do - Buffer.add_channel buf ic 1 + Caml.Buffer.add_channel buf ic 1 done with End_of_file -> ()); - let _ = Unix.close_process (ic, oc) in + let _ : Core.Unix.Exit_or_signal.t = Unix.close_process (ic, oc) in (Buffer.contents buf) let slice s e l = @@ -358,7 +360,7 @@ let slice s e l = List.slice l s e;; let random_choice l = - Random.int (List.length l) |> + Random.int (List.length l) |> List.nth_exn l let compare_list c xs ys = @@ -369,7 +371,7 @@ let compare_list c xs ys = let d = c a u in if d = 0 then r b v else d | _ -> assert false - in + in if d = 0 then r xs ys else d @@ -397,13 +399,13 @@ let push_resizable a x = let get_resizable a i = assert (i < a.ra_occupancy); Array.get a.ra_contents i |> get_some - + let set_resizable a i v = assert (i < a.ra_occupancy); Array.set a.ra_contents i (Some(v)) - + let rec ensure_resizable_length a l default = - if a.ra_occupancy >= l then () else + if a.ra_occupancy >= l then () else (push_resizable a default; ensure_resizable_length a l default) let clear_resizable a = diff --git a/solvers/versionDemo.ml b/solvers/versionDemo.ml index 4fb44dfba..5afe953b9 100644 --- a/solvers/versionDemo.ml +++ b/solvers/versionDemo.ml @@ -3,7 +3,7 @@ open Versions open Program open Utils -let _ = +let _ : unit = let t = new_version_table() in let p = "(#(lambda (lambda (* $2 (+ (lambda $2) $0)))) $0 2)" |> parse_program |> get_some in p |> incorporate t |> inline t |> extract t |> List.iter ~f:(fun p' -> @@ -13,7 +13,7 @@ let _ = ;; -let _ = +let _ : unit = List.range 0 6 |> List.iter ~f:(fun sz -> let p0 = List.range 0 sz |> List.fold_right ~init:"(+ 1 1)" ~f:(fun _ -> Printf.sprintf "(+ 1 %s)") |> @@ -23,7 +23,7 @@ let _ = List.range 1 4 |> List.iter ~f:(fun a -> let v = new_version_table() in let j = incorporate v p0 in - let r = List.range 0 a |> + let [@warning "-8"] r = List.range 0 a |> List.fold_right ~init:[j] ~f:(fun _ (a :: b) -> recursive_inversion v a :: a :: b) |> union v in @@ -44,5 +44,3 @@ let _ = (* (unique_space v r |> log_version_size v |> exp); *) flush_everything() )) - - diff --git a/solvers/versions.ml b/solvers/versions.ml index 3adef135e..b37a769e7 100644 --- a/solvers/versions.ml +++ b/solvers/versions.ml @@ -1,5 +1,4 @@ open Core -open Enumeration open Program open Utils open Type @@ -14,6 +13,7 @@ type vs = | IndexSpace of int | TerminalSpace of program | Universe | Void +[@@deriving equal] type vt = {universe : int; void : int; @@ -27,7 +27,7 @@ type vt = {universe : int; let index_table t index = get_resizable t.i2s index let version_table_size t = t.i2s.ra_occupancy -let clear_dynamic_programming_tables {n_step_table; substitution_table;} = +let clear_dynamic_programming_tables {n_step_table; substitution_table;_} = Hashtbl.clear n_step_table; Hashtbl.clear substitution_table;; let deallocate_versions v = @@ -92,7 +92,7 @@ let union t vs = | [] -> t.void | [v] -> v | _ -> incorporate_space t (Union(vs)) - + let rec incorporate t e = match e with | Index(i) -> version_index t i @@ -117,14 +117,14 @@ let rec extract t j = | Universe -> [primitive "UNIVERSE" t0 ()] let rec child_spaces t j = - (j :: + (j :: match index_table t j with | Union(u) -> List.map u ~f:(child_spaces t) |> List.concat | ApplySpace(f,x) -> child_spaces t f @ child_spaces t x | AbstractSpace(b) -> child_spaces t b | _ -> []) |> List.dedup_and_sort ~compare:(-) - + let rec shift_free ?c:(c=0) t ~n ~index = if n = 0 then index else match index_table t index with @@ -153,7 +153,7 @@ let rec shift_versions ?c:(c=0) t ~n ~index = | AbstractSpace(b) -> version_abstract t (shift_versions ~c:(c+1) t ~n:n ~index:b) | TerminalSpace(_) | Universe | Void -> index - + let rec subtract t a b = match index_table t a, index_table t b with @@ -173,11 +173,11 @@ let rec subtract t a b = version_apply t f1 (subtract t x1 x2)] | ApplySpace(_,_), _ -> a | IndexSpace(i1), IndexSpace(i2) when i1 = i2 -> t.void - | IndexSpace(i1), _ -> a - | TerminalSpace(t1), TerminalSpace(t2) when t1 = t2 -> t.void + | IndexSpace(_), _ -> a + | TerminalSpace(t1), TerminalSpace(t2) when equal_program t1 t2 -> t.void | TerminalSpace(_), _ -> a - + let rec unique_space t a = match index_table t a with | Universe | Void | IndexSpace(_) | TerminalSpace(_) -> a @@ -195,7 +195,7 @@ let rec intersection t a b = | Void, _ | _, Void -> t.void | Union(xs), Union(ys) -> xs |> List.concat_map ~f:(fun x -> ys |> List.map ~f:(fun y -> intersection t x y)) |> union t - | Union(xs), _ -> + | Union(xs), _ -> xs |> List.map ~f:(fun x -> intersection t x b) |> union t | _, Union(xs) -> xs |> List.map ~f:(fun x -> intersection t x a) |> union t @@ -204,7 +204,7 @@ let rec intersection t a b = | ApplySpace(f1,x1), ApplySpace(f2,x2) -> version_apply t (intersection t f1 f2) (intersection t x1 x2) | IndexSpace(i1), IndexSpace(i2) when i1 = i2 -> a - | TerminalSpace(t1), TerminalSpace(t2) when t1 = t2 -> a + | TerminalSpace(t1), TerminalSpace(t2) when equal_program t1 t2 -> a | _ -> t.void let inline t j = @@ -243,7 +243,7 @@ let inline t j = | Void | Universe | TerminalSpace(_) -> t.void in il [] j - + let rec recursive_inlining t j = (* Constructs vs of all programs that are 1 inlining step away from a program in provided vs *) match index_table t j with @@ -257,11 +257,11 @@ let rec recursive_inlining t j = | ApplySpace(f,x) -> version_apply t f (recursive_inlining t x) | Union(u) -> u |> List.map ~f:inline_arguments |> union t | AbstractSpace(_) | TerminalSpace(_) | Universe | Void | IndexSpace(_) -> t.void - in + in let argument_linings = inline_arguments j in union t [top_linings; argument_linings;] - - + + let rec have_intersection ?table:(table=None) t a b = if a = b then true else @@ -274,7 +274,7 @@ let rec have_intersection ?table:(table=None) t a b = | _, Universe -> true | Union(xs), Union(ys) -> xs |> List.exists ~f:(fun x -> ys |> List.exists ~f:(fun y -> have_intersection ~table t x y)) - | Union(xs), _ -> + | Union(xs), _ -> xs |> List.exists ~f:(fun x -> have_intersection ~table t x b) | _, Union(xs) -> xs |> List.exists ~f:(fun x -> have_intersection ~table t x a) @@ -283,10 +283,10 @@ let rec have_intersection ?table:(table=None) t a b = | ApplySpace(f1,x1), ApplySpace(f2,x2) -> have_intersection ~table t f1 f2 && have_intersection ~table t x1 x2 | IndexSpace(i1), IndexSpace(i2) when i1 = i2 -> true - | TerminalSpace(t1), TerminalSpace(t2) when t1 = t2 -> true + | TerminalSpace(t1), TerminalSpace(t2) when equal_program t1 t2 -> true | _ -> false in - + match table with | None -> intersect a b | Some(table') -> @@ -306,13 +306,13 @@ let rec substitutions t ?n:(n=0) index = let s = shift_free t ~n:n ~index in let m = Hashtbl.Poly.create() in - if s <> t.void then ignore(Hashtbl.add m ~key:s ~data:(version_index t n)); + if s <> t.void then ignore(Hashtbl.add m ~key:s ~data:(version_index t n) : [ `Duplicate | `Ok ]); - begin + begin match index_table t index with - | TerminalSpace(_) -> ignore(Hashtbl.add m ~key:t.universe ~data:index) + | TerminalSpace(_) -> ignore(Hashtbl.add m ~key:t.universe ~data:index : [ `Duplicate | `Ok ]) | IndexSpace(i) -> - ignore(Hashtbl.add m ~key:t.universe ~data:(if i < n then index else version_index t (1+i))) + ignore(Hashtbl.add m ~key:t.universe ~data:(if i < n then index else version_index t (1+i)) : [ `Duplicate | `Ok ]) | AbstractSpace(b) -> substitutions t ~n:(n+1) b |> Hashtbl.iteri ~f:(fun ~key ~data -> Hashtbl.add_exn m ~key ~data:(version_abstract t data)) @@ -324,7 +324,7 @@ let rec substitutions t ?n:(n=0) index = | Some(stuff) -> Hashtbl.set new_mapping ~key:v ~data:(b :: stuff) | None -> Hashtbl.set new_mapping ~key:v ~data:[b])); new_mapping |> Hashtbl.iteri ~f:(fun ~key ~data -> - Hashtbl.set m ~key ~data:(union t data)) + Hashtbl.set m ~key ~data:(union t data)) | ApplySpace(f, x) when !factored_substitution -> let new_mapping = Hashtbl.Poly.create() in @@ -333,7 +333,7 @@ let rec substitutions t ?n:(n=0) index = fm |> Hashtbl.iteri ~f:(fun ~key:v1 ~data:f -> xm |> Hashtbl.iteri ~f:(fun ~key:v2 ~data:x -> - if have_intersection t v1 v2 then + if have_intersection t v1 v2 then Hashtbl.update new_mapping (intersection t v1 v2) ~f:(function | None -> ([f],[x]) | Some(fs,xs) -> (f :: fs, x :: xs)))); @@ -342,7 +342,7 @@ let rec substitutions t ?n:(n=0) index = let xs = union t xs in Hashtbl.set m ~key ~data:(version_apply t fs xs)) - | ApplySpace(f, x) -> + | ApplySpace(f, x) -> let new_mapping = Hashtbl.Poly.create() in let fm = substitutions t ~n f in let xm = substitutions t ~n x in @@ -358,7 +358,7 @@ let rec substitutions t ?n:(n=0) index = end)); new_mapping |> Hashtbl.iteri ~f:(fun ~key ~data -> - Hashtbl.set m ~key ~data:(union t data)) + Hashtbl.set m ~key ~data:(union t data)) | _ -> () end; @@ -368,7 +368,7 @@ let rec substitutions t ?n:(n=0) index = let inversion t j = substitutions t j |> Hashtbl.to_alist |> List.filter_map ~f:(fun (v,b) -> - if v = t.universe || index_table t b = IndexSpace(0) then None else + if v = t.universe || equal_vs (index_table t b) (IndexSpace(0)) then None else Some(version_apply t (version_abstract t b) v)) |> union t @@ -376,13 +376,13 @@ let rec recursive_inversion t j = match get_resizable t.recursive_inversion_table j with | Some(ri) -> ri | None -> - let ri = + let ri = match index_table t j with | Union(u) -> union t (u |> List.map ~f:(recursive_inversion t)) | _ -> let top_inversions = substitutions t j |> Hashtbl.to_alist |> List.filter_map ~f:(fun (v,b) -> - if v = t.universe || index_table t b = IndexSpace(0) then None else + if v = t.universe || equal_vs (index_table t b) (IndexSpace(0)) then None else Some(version_apply t (version_abstract t b) v)) in let child_inversions = match index_table t j with @@ -396,7 +396,7 @@ let rec recursive_inversion t j = set_resizable t.recursive_inversion_table j (Some(ri)); ri -let beta_pruning t j = +let beta_pruning t j = let rec beta_pruning' ?isApplied:(isApplied=false) ?canBeta:(canBeta=true) t j = match index_table t j with @@ -415,18 +415,18 @@ let rec beta_pruning' ?isApplied:(isApplied=false) ?canBeta:(canBeta=true) u |> List.map ~f:(beta_pruning' ~isApplied ~canBeta t) |> union t | IndexSpace(_) | TerminalSpace(_) | Universe | Void -> j in beta_pruning' t j - + let rec log_version_size t j = match index_table t j with | ApplySpace(f,x) -> log_version_size t f +. log_version_size t x | AbstractSpace(b) -> log_version_size t b | Union(u) -> u |> List.map ~f:(log_version_size t) |> lse_list | _ -> 0. -let rec n_step_inversion ?inline:(il=false) t ~n j = +let n_step_inversion ?inline:(il=false) t ~n j = let key = (n, j) in match Hashtbl.find t.n_step_table key with | Some(ns) -> ns - | None -> + | None -> (* list of length (n+1), corresponding to 0 steps, 1, ..., n *) (* Each "step" is the union of an inverse inlining step and optionally an inlining step *) let rec n_step ?completed:(completed=0) current : int list = @@ -440,9 +440,9 @@ let rec n_step_inversion ?inline:(il=false) t ~n j = union t [recursive_inversion t v; i] else recursive_inversion t v - in + in let rest = if completed = n then [] else - n_step ~completed:(completed+1) (step current) + n_step ~completed:(completed+1) (step current) in beta_pruning t current :: rest in @@ -453,12 +453,12 @@ let rec n_step_inversion ?inline:(il=false) t ~n j = | ApplySpace(f,x) -> version_apply t (visit f) (visit x) | AbstractSpace(b) -> version_abstract t (visit b) | IndexSpace(_) | TerminalSpace(_) -> j - in + in union t (children :: n_step j) - in + in let ns = visit j |> beta_pruning t in - Hashtbl.set t.n_step_table key ns; + Hashtbl.set t.n_step_table ~key ~data:ns; ns (* let n_step_inversion ?inline:(il=false) t ~n j = *) @@ -507,8 +507,8 @@ let rec n_step_inversion ?inline:(il=false) t ~n j = (* end; *) (* ground_truth *) - - + + let reachable_versions t indices : int list = let visited = Hash_set.Poly.create() in @@ -541,7 +541,7 @@ let garbage_collect_versions ?verbose:(verbose=false) t indices = Printf.eprintf "Garbage collection reduced table to %d%% of previous size\n" (100*nt.i2s.ra_occupancy/t.i2s.ra_occupancy); (nt, indices) - + (* cost calculations *) let epsilon_cost = 0.01;; @@ -557,27 +557,28 @@ let empty_cost_table t = {function_cost = empty_resizable(); let rec minimum_cost_inhabitants ?given:(given=None) ?canBeLambda:(canBeLambda=true) t j : float*(int list) = let caching_table = if canBeLambda then t.argument_cost else t.function_cost in ensure_resizable_length caching_table (j + 1) None; - + match get_resizable caching_table j with | Some(c) -> c | None -> let c = match given with | Some(invention) when have_intersection t.cost_table_parent invention j -> (1., [invention]) - | _ -> + | _ -> match index_table t.cost_table_parent j with | Universe | Void -> assert false | IndexSpace(_) | TerminalSpace(_) -> (1., [j]) | Union(u) -> let children = u |> List.map ~f:(minimum_cost_inhabitants ~given ~canBeLambda t) in - let c = children |> List.map ~f:(fun (cost,_) -> cost) |> fold1 min in + let c = children |> List.map ~f:fst |> fold1 Float.min in if is_invalid c then (c,[]) else + let open Float in let children = children |> List.filter ~f:(fun (cost,_) -> cost = c) in - (c, children |> List.concat_map ~f:(fun (_,p) -> p)) + (c, children |> List.concat_map ~f:snd) | AbstractSpace(b) when canBeLambda -> let cost, children = minimum_cost_inhabitants ~given ~canBeLambda:true t b in (cost+.epsilon_cost, children |> List.map ~f:(version_abstract t.cost_table_parent)) - | AbstractSpace(b) -> (Float.infinity,[]) + | AbstractSpace(_) -> (Float.infinity,[]) | ApplySpace(f,x) -> let fc, fs = minimum_cost_inhabitants ~given ~canBeLambda:false t f in let xc, xs = minimum_cost_inhabitants ~given ~canBeLambda:true t x in @@ -603,25 +604,25 @@ let rec minimal_inhabitant_cost ?intersectionTable:(intersectionTable=None) ?given:(given=None) ?canBeLambda:(canBeLambda=true) t j : float = let caching_table = if canBeLambda then t.argument_cost else t.function_cost in ensure_resizable_length caching_table (j + 1) None; - + match get_resizable caching_table j with | Some(c) -> c | None -> let c = match given with | Some(invention) when have_intersection ~table:intersectionTable t.cost_table_parent invention j -> 1. - | _ -> + | _ -> match index_table t.cost_table_parent j with | Universe | Void -> assert false | IndexSpace(_) | TerminalSpace(_) -> 1. | Union(u) -> - u |> List.map ~f:(minimal_inhabitant_cost ~intersectionTable ~given ~canBeLambda t) |> fold1 min + u |> List.map ~f:(minimal_inhabitant_cost ~intersectionTable ~given ~canBeLambda t) |> fold1 Float.min | AbstractSpace(b) when canBeLambda -> epsilon_cost +. minimal_inhabitant_cost ~intersectionTable ~given ~canBeLambda:true t b - | AbstractSpace(b) -> Float.infinity + | AbstractSpace(_) -> Float.infinity | ApplySpace(f,x) -> epsilon_cost +. minimal_inhabitant_cost ~intersectionTable ~given ~canBeLambda:false t f +. - minimal_inhabitant_cost ~intersectionTable ~given ~canBeLambda:true t x + minimal_inhabitant_cost ~intersectionTable ~given ~canBeLambda:true t x in set_resizable caching_table j (Some(c)); c @@ -636,7 +637,7 @@ let rec minimal_inhabitant match c, given with | 1., Some(invention) when have_intersection ~table:intersectionTable t.cost_table_parent invention j -> extract t.cost_table_parent invention |> singleton_head - | _ -> + | _ -> match vs with | Universe | Void -> assert false | IndexSpace(_) | TerminalSpace(_) -> @@ -660,9 +661,9 @@ type beam = {default_function_cost : float; let narrow ~bs b = let narrow bm = - if Hashtbl.length bm > bs then - let sorted = Hashtbl.to_alist bm |> List.sort ~compare:(fun (_,c1) (_,c2) -> Float.compare c1 c2) in - Hashtbl.Poly.of_alist_exn (List.take sorted bs) + if Hashtbl.length bm > bs then + let sorted = Hashtbl.to_alist bm |> List.sort ~compare:(fun (_,c1) (_,c2) -> Float.compare c1 c2) in + Hashtbl.Poly.of_alist_exn (List.take sorted bs) else bm in b.relative_function <- narrow b.relative_function; @@ -671,7 +672,7 @@ let narrow ~bs b = let relax table key data = match Hashtbl.find table key with | None -> Hashtbl.set table ~key ~data - | Some(old) when old > data -> Hashtbl.set table ~key ~data + | Some(old) when Float.(>) old data -> Hashtbl.set table ~key ~data | Some(_) -> () ;; let relative_function b i = match Hashtbl.find b.relative_function i with @@ -693,7 +694,7 @@ let calculate_candidate_costs v candidates = List.dedup_and_sort ~compare:(-) |> List.length |> Float.of_int in Hashtbl.set candidate_cost ~key:k ~data:(1.+.cost)); candidate_cost - + let beam_costs'' ~ct ~bs (candidates : int list) (frontier_indices : (int list) list) : beam option ra = @@ -706,7 +707,7 @@ let beam_costs'' ~ct ~bs (candidates : int list) (frontier_indices : (int list) let candidate_cost = calculate_candidate_costs v candidates' in let rec calculate_costs j = - ensure_resizable_length caching_table (j + 1) None; + ensure_resizable_length caching_table (j + 1) None; match get_resizable caching_table j with | Some(bm) -> bm | None -> @@ -746,7 +747,7 @@ let beam_costs'' ~ct ~bs (candidates : int list) (frontier_indices : (int list) bm in - frontier_indices |> List.iter ~f:(List.iter ~f:(fun j -> ignore(calculate_costs j))); + frontier_indices |> List.iter ~f:(List.iter ~f:(fun j -> ignore(calculate_costs j : beam))); caching_table @@ -759,16 +760,16 @@ let beam_costs' ~ct ~bs (candidates : int list) (frontier_indices : (int list) l let score i = let corpus_size = frontier_beams |> List.map ~f:(fun bs -> - bs |> List.map ~f:(fun b -> min (relative_argument b i) (relative_function b i)) |> - fold1 min) |> fold1 (+.) + bs |> List.map ~f:(fun b -> Float.min (relative_argument b i) (relative_function b i)) |> + fold1 Float.min) |> fold1 (+.) in corpus_size in candidates |> List.map ~f:score - - + + let beam_costs ~ct ~bs (candidates : int list) (frontier_indices : (int list) list) = let scored = List.zip_exn (beam_costs' ~ct ~bs candidates frontier_indices) candidates in scored |> List.sort ~compare:(fun (s1,_) (s2,_) -> Float.compare s1 s2) @@ -778,7 +779,7 @@ let batched_refactor ~ct (candidates : int list) (frontier_indices : (int list) let caching_table = beam_costs'' ~ct ~bs:(List.length candidates) candidates frontier_indices in let v = ct.cost_table_parent in - + let rec refactor ~canBeLambda i j = let inhabitants = minimum_cost_inhabitants ~canBeLambda:true ct j |> snd in diff --git a/versionDemo b/versionDemo index 6d81088e4..cc95e884d 100755 Binary files a/versionDemo and b/versionDemo differ