{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "pair_computation (generic function with 1 method)" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "using JLD\n", "include(\"Transformation.jl\")\n", "include(\"AbstractSystem.jl\")\n", "include(\"Tree.jl\")\n", "include(\"Evaluation.jl\")\n", "include(\"BackPropogation.jl\")\n", "include(\"Facility.jl\")\n", "import Base.push!" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(::fs) (generic function with 3 methods)" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type Axiom\n", " tree1 :: Tree\n", " tree2 :: Tree\n", " index :: Dict\n", "end\n", "\n", "function Base.show(io :: IO, m :: Axiom)\n", " print(io, \"Axiom[\")\n", " print(io, m.tree1)\n", " print(io, \", \")\n", " print(io, m.tree2)\n", " print(io, \"]\")\n", "end\n", "\n", "function beautify(m :: Axiom)\n", " string(\"Axiom:\\n\", beautify(m.tree1, 1), \"\\n\", beautify(m.tree2, 1), \"\\n\")\n", "end\n", "\n", "Axiom(tree1 :: Tree, tree2 :: Tree) = Axiom(tree1, tree2, add!(index(tree1), index(tree2)))\n", "\n", "Axiom(skeleton1, skeleton2) = Axiom(toTree(skeleton1), toTree(skeleton2))\n", "\n", "function push!(index :: Dict, ops :: Array)\n", " n = length(ops)\n", " for i in 1:n\n", " for t in index[i]\n", " t.op = ops[i]\n", " end\n", " end\n", "end\n", "\n", "function push!(index :: Dict, ops :: Dict)\n", " for key in keys(ops)\n", " if haskey(index, key)\n", " ts = index[key]\n", " for t in ts\n", " t.op = ops[key]\n", " end\n", " end\n", " end\n", "end\n", "\n", "function push!(axiom :: Axiom, ops)\n", " push!(axiom.index, variables)\n", "end\n", "\n", "function init_axiom!(axiom :: Axiom, variables)\n", " push!(axiom.index, variables)\n", " init_tree!(axiom.tree1)\n", " init_tree!(axiom.tree2)\n", "end\n", "\n", "init_axioms! = distribute(init_axiom!)\n", "\n", "## add some loss function to deal with degenerating problem?\n", "\n", "function loss(a, b)\n", " b * (1. - a * b)\n", "end\n", "\n", "function train_axiom!(axiom :: Axiom, variables, n = 1, randomize = identity)\n", " push!(axiom.index, variables)\n", " d1 :: Array{Float64, 1} = axiom.tree1.value[:d]\n", " d2 :: Array{Float64, 1} = axiom.tree2.value[:d]\n", " v1 :: Array{Float64, 1} = axiom.tree1.value[:value]\n", " v2 :: Array{Float64, 1} = axiom.tree2.value[:value]\n", " for i in 1:n\n", " randomize(variables)\n", " push!(axiom.index, variables)\n", " eval_tree!(axiom.tree2)\n", " eval_tree!(axiom.tree1)\n", " for j in 1:length(d1)\n", " d1[j] = loss(v1[j], v2[j])\n", " d2[j] = loss(v2[j], v1[j])\n", " end\n", " bp_tree!(axiom.tree1)\n", " bp_tree!(axiom.tree2)\n", " end\n", "end\n", "\n", "train_axioms! = distribute(train_axiom!)\n", "\n", "## to prevent degeneration problem, we use anti-traing to deal with the problem.\n", "\n", "function anti_train_axiom!(axiom :: Axiom, n = 1, randomize = identity)\n", " d1 :: Array{Float64, 1} = axiom.tree1.value[:d]\n", " d2 :: Array{Float64, 1} = axiom.tree2.value[:d]\n", " v1 :: Array{Float64, 1} = axiom.tree1.value[:value]\n", " v2 :: Array{Float64, 1} = axiom.tree2.value[:value]\n", " for i in 1:n\n", " randomize(axiom.tree1)\n", " randomize(axiom.tree2)\n", " eval_tree!(axiom.tree2)\n", " eval_tree!(axiom.tree1)\n", " for j in 1:length(d1)\n", " d1[j] = - loss(v1[j], v2[j])\n", " d2[j] = - loss(v2[j], v1[j])\n", " end\n", " bp_tree!(axiom.tree1)\n", " bp_tree!(axiom.tree2)\n", " end\n", "end\n", "\n", "anti_train_axioms! = distribute(anti_train_axiom!)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Module.List(Frame->Env)" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "include(\"DataStructs.jl\")\n", "\n", "UChar = Class(\"Char\", 8)\n", "Variable = Class(\"Variable\", 100)\n", "Stream = List(UChar, Variable, [:v, :u, :v1])\n", "\n", "Prog = Class(\"Prog\", 100)\n", "Bindingc = Class(\"Binding\", 100)\n", "Binding = Pair(Variable, Prog, Bindingc, [:b, :v, :p])\n", "\n", "Framec = Class(\"Frame\", 100)\n", "Frame = List(Bindingc, Framec, [:f1, :b, :f2])\n", "\n", "Envc = Class(\"Env\", 200)\n", "Env = List(Framec, Envc, [:e1, :f, :e2])" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Func(eval){Prog,Env->Env}" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lookup = DFunction(\"lookup\", [Envc, Variable], Prog)\n", "set = DFunction(\"set\", [Envc, Variable, Prog], Envc)\n", "add_binding = DFunction(\"add_binding\", [Framec, Variable, Prog], Framec)\n", "def = DFunction(\"def\", [Envc, Variable, Prog], Envc)\n", "extend = DFunction(\"extend\", [Envc, Variable, Prog], Envc)\n", "\n", "var = DFunction(\"var\", [Variable], Prog)\n", "definition = DFunction(\"definition\", [Variable, Prog], Prog) \n", "assignment = DFunction(\"assignment\", [Variable, Prog], Prog) \n", "procedure = DFunction(\"procedure\", [Variable, Prog], Prog)\n", "func_call = DFunction(\"func_call\", [Prog, Prog], Prog)\n", "Seq = List(Prog, Prog)\n", "\n", "f_eval = DFunction(\"f_eval\", [Prog, Envc], Prog)\n", "s_eval = DFunction(\"eval\", [Prog, Envc], Envc)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "23-element Array{Symbol,1}:\n", " :Binding \n", " :Bindingc \n", " :Env \n", " :Envc \n", " :Frame \n", " :Framec \n", " :Prog \n", " :Seq \n", " :Stream \n", " :UChar \n", " :Variable \n", " :add_binding\n", " :assignment \n", " :def \n", " :definition \n", " :extend \n", " :f_eval \n", " :func_call \n", " :lookup \n", " :procedure \n", " :s_eval \n", " :set \n", " :var " ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "## @load \"test.jld\"" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Axiom[[Func(extend){Env,Variable,Prog->Env}, e, v, p], [Func(def){Env,Variable,Prog->Env}, [Func(cons){Frame,Env->Env}, Obj(empty){Frame}, e], v, p]]" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "axiom_lookup1 = Axiom([lookup, [Env.cons, [Frame.cons, [Binding.pair, :v, :p], :f], :e], :v], :p)\n", "axiom_lookup2 = Axiom([lookup, [Env.cons, [Frame.cons, [Binding.pair, :v1, :p1], :f2], :e2], :v2], \n", " [lookup, [Env.cons, :f2, :e2], :v2])\n", "axiom_lookup3 = Axiom([lookup, [Env.cons, Frame.empty, :e], :v], [lookup, :e, :v])\n", "\n", "axiom_set1 = Axiom([set, [Env.cons, [Frame.cons, [Binding.pair, :v1, :p1], :f2], :e2], :v1, :p2], \n", " [Env.cons, [Frame.cons, [Binding.pair, :v1, :p2], :f2], :e2])\n", "axiom_set2 = Axiom([set, [Env.cons, [Frame.cons, [Binding.pair, :v1, :p1], :f2], :e2], :v2, :p2], \n", " [Env.cons, [Frame.cons, [Binding.pair, :v1, :p1], \n", " [Env.first, [set, [Env.cons, :f2, :e2], :v2, :p2]]], \n", " [Env.rest, [set, [Env.cons, :f2, :e2], :v2, :p2]]])\n", "axiom_set3 = Axiom([set, [Env.cons, Frame.empty, :e], :v, :p], [Env.cons, Frame.empty, [set, :e, :v, :p]])\n", "\n", "axiom_add_binding = Axiom([add_binding, :f, :v, :p], [Frame.cons, [Binding.pair, :v, :p], :f])\n", "axiom_def = Axiom([def, :e, :v, :p], [Env.first!, :e, [add_binding, [Env.first, :e], :v, :p]])\n", "axiom_extend = Axiom([extend, :e, :v, :p], [def, [Env.cons, Frame.empty, :e], :v, :p])" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Axiom[[Func(f_eval){Prog,Env->Prog}, [Func(cons){Prog,Prog->Prog}, p1, p2], e], [Func(f_eval){Prog,Env->Prog}, p2, [Func(eval){Prog,Env->Env}, p1, e]]]" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "axiom_var_s = Axiom([s_eval, [var, :v], :e], :e)\n", "axiom_var_f = Axiom([f_eval, [var, :v], :e], [lookup, :e, :v])\n", "axiom_definition_s = Axiom([s_eval, [definition, :v, :p], :e], [def, [s_eval, :p, :e], :v, [f_eval, :p, :e]])\n", "axiom_definition_f = Axiom([f_eval, [definition, :v, :p], :e], [f_eval, :p, :e])\n", "axiom_assignment_s = Axiom([s_eval, [assignment, :v, :p], :e], [set, [s_eval, :p, :e], :v, [f_eval, :p, :e]])\n", "axiom_assignment_f = Axiom([f_eval, [assignment, :v, :p], :e], [f_eval, :p, :e])\n", "axiom_proc_s = Axiom([s_eval, [procedure, :v, :p], :e], :e)\n", "axiom_proc_f = Axiom([f_eval, [procedure, :v, :p], :e], [procedure, :v, :p])\n", "axiom_func_s1 = Axiom([s_eval, [func_call, :p1, :p2], :e], \n", " [s_eval, [func_call, [f_eval, :p1, :e], [f_eval, :p2, :e]], :e])\n", "axiom_func_f1 = Axiom([f_eval, [func_call, :p1, :p2], :e], \n", " [f_eval, [func_call, [f_eval, :p1, :e], [f_eval, :p2, :e]], :e])\n", "axiom_func_s2 = Axiom([s_eval, [func_call, [procedure, :v, :p1], :p2], :e], \n", " [Env.rest, [s_eval, :p1, [extend, :e, :v, :p2]]])\n", "axiom_func_f2 = Axiom([f_eval, [func_call, [procedure, :v, :p1], :p2], :e], [f_eval, :p1, [extend, :e, :v, :p2]])\n", "axiom_seq_s = Axiom([s_eval, [Seq.cons, :p1, :p2], :e], [s_eval, :p2, [s_eval, :p1, :e]])\n", "axiom_seq_f = Axiom([f_eval, [Seq.cons, :p1, :p2], :e], [f_eval, :p2, [s_eval, :p1, :e]])" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [], "source": [ "axioms = Dict()\n", "axioms_lookup = [axiom_lookup1, axiom_lookup2, axiom_lookup3]\n", "axioms_set = [axiom_set1, axiom_set2, axiom_set3]\n", "axioms[:base_env] = [Stream.axioms, Binding.axioms, Frame.axioms, Env.axioms]\n", "axioms[:env] = [axioms_lookup, axioms_set, axiom_add_binding, axiom_def, axiom_extend]\n", "axioms_v = [axiom_var_s, axiom_var_f]\n", "axioms_d = [axiom_definition_s, axiom_definition_f]\n", "axioms_a = [axiom_assignment_s, axiom_assignment_f]\n", "axioms_p = [axiom_proc_s, axiom_proc_f]\n", "axioms_f = [axiom_func_s1, axiom_func_f1, axiom_func_s2, axiom_func_f2]\n", "axioms_s = [axiom_seq_s, axiom_seq_f]\n", "axioms[:prog] = [axioms_v, axioms_d, axioms_a, axioms_p, axioms_f, axioms_s];" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "REPL(Obj(empty){Env},Obj(empty){Prog})" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "## The Repl facility, note that for the program structure parsing, we rely on the julia parser;\n", "## and we also need to read the variable name from string.\n", "include(\"Repl.jl\")\n", "r = REPL(Env.empty, Seq.empty)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "object_init (generic function with 4 methods)" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "function object_init(dict :: Dict, name, num :: Int64, class :: Class)\n", " dict[Symbol(name, num)] = Object(string(name, num), class)\n", "end\n", "\n", "function object_init(dict :: Dict, name, class :: Class)\n", " dict[Symbol(name)] = Object(string(name), class)\n", "end\n", "\n", "function object_init(dict :: Dict, name_dict :: Dict, num :: Int64)\n", " for k in keys(name_dict)\n", " object_init(dict, k, name_dict[k])\n", " for i in 1:num\n", " object_init(dict, k, i, name_dict[k])\n", " end\n", " end\n", "end\n", "\n", "function object_init(dict :: Dict, name_dict :: Dict)\n", " for k in keys(name_dict)\n", " object_init(dict, k, name_dict[k])\n", " end\n", "end" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "Memory" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type Memory\n", " class :: Class\n", " mclass :: Class\n", " \n", " encode :: DFunction\n", " decode :: DFunction\n", " \n", " axioms :: Array{Axiom, 1}\n", "end\n", "\n", "function Base.show(io :: IO, m :: Memory)\n", " print(io, string(\"Module.Memory(\", m.class.class_name, \"->\", m.mclass.class_name, \")\"))\n", "end\n", "\n", "function Memory(class :: Class, mclass :: Class, symbols = [:s, :m])\n", " encode = DFunction(\"encode\", [class], mclass)\n", " decode = DFunction(\"decode\", [mclass], class)\n", " \n", " sym = symbols[1]\n", " msym = symbols[2]\n", " axiom1 = Axiom([decode, [encode, sym]], sym)\n", " axiom2 = Axiom([encode, [decode, msym]], msym)\n", " axioms = [axiom1, axiom2]\n", " \n", " Memory(class, mclass, encode, decode, axioms)\n", "end\n", "\n", "function Memory(class :: Class, type_len :: Int64, symbols = [:s, :m])\n", " memory_name = string(\"Memory\", \"_\", class.class_name)\n", " mclass = Class(memory_name, type_len)\n", " Memory(class, mclass, symbols)\n", "end\n", "\n", "## @time l = List(Sensor, 70)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "another_naive_randomize (generic function with 1 method)" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "naive_randomize = distribute(function(o :: Object) randn!(o.value) end)\n", "\n", "function another_naive_randomize(tree :: Tree)\n", " foreach(another_naive_randomize, tree.subtrees)\n", " if typeof(tree.op) == Object\n", " randn!(tree.op.value)\n", " end\n", " tree\n", "end" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# UChar = Class(\"Char\", 8)\n", "# Variable = Class(\"Variable\", 100)\n", "# Prog = Class(\"Prog\", 100)\n", "# Bindingc = Class(\"Binding\", 100)\n", "# Binding = Pair(Variable, Prog, Bindingc, [:b, :v, :p])\n", "# Framec = Class(\"Frame\", 100)\n", "# Frame = List(Bindingc, Framec, [:f1, :b, :f2])\n", "# Envc = Class(\"Env\", 200)\n", "# Env = List(Framec, Envc, [:e1, :f, :e2])\n", "\n", "dict = Dict()\n", "ndict = Dict()\n", "ndict[:u] = UChar\n", "ndict[:v] = Variable\n", "ndict[:p] = Prog\n", "ndict[:b] = Bindingc\n", "ndict[:f] = Framec\n", "ndict[:e] = Envc\n", "object_init(dict, ndict, 2)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 0.820412 seconds (746.11 k allocations: 34.340 MB, 2.33% gc time)\n", " 30.175189 seconds (1.69 M allocations: 34.976 MB, 0.05% gc time)\n", "278.739172 seconds (15.82 M allocations: 274.529 MB, 0.01% gc time)\n" ] } ], "source": [ "@time init_axioms!(axioms, dict)\n", "@time anti_train_axioms!(axioms, 1000, another_naive_randomize)\n", "## init_axioms!(axioms, dict)\n", "## train_axioms!(axioms, dict, 1000)\n", "## @time anti_train_axioms!(axioms, 10000, another_naive_randomize)\n", "@time train_axioms!(axioms, dict, 10000, naive_randomize)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [], "source": [ "a1 = repl(r, \"function(x) x end\").value;\n", "a2 = repl(r, \"var y = function(x) x end\").value;\n", "a3 = repl(r, \"y\").value;\n", "a4 = repl(r, \"function(x) x(x) end\").value;\n", "a5 = repl(r, \"begin var y = function(x) x end; y end\").value;\n", "as = [a1, a2, a3, a4, a5];" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Result for pair 1 and 2 is 31.945527848864803.\n", "Result for pair 1 and 3 is 55.973554989290875.\n", "Result for pair 1 and 4 is 12.184253007679537.\n", "Result for pair 1 and 5 is 84.90008920339665.\n", "Result for pair 2 and 3 is 27.83942832108043.\n", "Result for pair 2 and 4 is 20.144262300399824.\n", "Result for pair 2 and 5 is 52.95456297977779.\n", "Result for pair 3 and 4 is 44.17229047178985.\n", "Result for pair 3 and 5 is 28.926534703487523.\n", "Result for pair 4 and 5 is 73.09882468589595.\n" ] } ], "source": [ "pair_computation(function(x, y) sum(abs(as[x] - as[y])) end, 1:5)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [], "source": [ "Interpreter = Dict()\n", "I_names = Dict()\n", "I_names[:base] = [:UChar, :Variable, :Stream, :Prog, :Bindingc, :Binding, :Framec, :Frame, :Envc, :Env]\n", "I_names[:env] = [:lookup, :set, :add_binding, :def, :extend]\n", "I_names[:prog] = [:var, :definition, :assignment, :procedure, :func_call, :Seq]\n", "I_names[:repl] = [:f_eval, :s_eval]\n", "inject(I_names, Interpreter)\n", "Interpreter\n", "\n", "## save(\"test.jld\", Interpreter)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "type Rewriter\n", " rule :: Function\n", "end" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "rewrite (generic function with 1 method)" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "function rewrite(t :: Array)\n", " if length(t) == 0\n", " t\n", " elseif typeof(t[1]) == Rewriter\n", " t[1].rule([rewrite(i) for i in t[2:end]])\n", " else\n", " t\n", " end\n", "end\n", "\n", "function rewrite(t)\n", " t\n", "end" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "ccc = Rewriter(function(x) end)" ] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Julia 0.5.0", "language": "julia", "name": "julia-0.5" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "0.5.0" } }, "nbformat": 4, "nbformat_minor": 1 }