split out unhygienic toy model

This commit is contained in:
msyds committed 2026-09-18 08:12:08 -06:00
1 parent d7d18472c9
commit 70ac846051
4 files changed
+136 -139

No files matched your search

-112
View File
@@ -110,118 +110,6 @@
(defn- merge-unify-with
([f] {})
([f a] a)
([f a b] (and a b (merge-with f a b)))
([f a b & xs] (reduce #(merge-unify-with f %1 %2) (cons a (cons b xs)))))
(defn- merge-unify [& xs]
(apply merge-unify-with (fn [_ x] x) xs))
(defn traverse [f xs]
(let [xs* (map f xs)]
(if (contains? xs* nil)
nil
xs*)))
(defn- unify* [pattern datum]
(match [pattern datum]
[[:wildcard _] _] {}
[[:var x] _] {x datum}
[[:list {:leading leading
:trailing nil
:ellipsis ellipsis}]
(_ :guard seq?)]
(let [[leading-datum ellipsis-datum] (split-at (count leading) datum)]
(merge-unify
(apply merge-unify (map #(unify* %1 %2)
leading
leading-datum))
(some->> ellipsis-datum
(map #(when-some [r (unify* ellipsis %)]
(->> r
(map (fn [[k v]] [k (list v)]))
(into {}))))
(apply merge-unify-with concat)
(map (fn [[k v]]
[k [:ellipsis v]]))
(into {}))))
[[:list {:leading leading}]
(_ :guard seq?)]
(when (= (count datum)
(count leading))
(->> (map #(unify* %1 %2) leading datum)
(apply merge-unify)))
;; no match
:else nil))
(defn unify [pattern datum]
(unify* (s/conform ::pattern pattern) datum))
(comment
(transcribe (unify '((a ...) ...)
'((1 2) (3 4) (5 6)))
'(begin (a ...) ...))
(strip-ellipsis
'[:ellipsis ([:ellipsis (1 2)] [:ellipsis (3 4)] [:ellipsis (5 6)])]
2))
(defn- strip-ellipsis [unif ellipsis-depth]
(match unif
[:ellipsis p]
(if (< 0 ellipsis-depth)
(map #(strip-ellipsis % (dec ellipsis-depth)) p)
(throw (ex-info "나쁜 점점점" {})))
:else unif))
(defn- transcribe*
([unification template]
(transcribe* 0 unification template))
([ellipsis-depth unification template]
(match template
[:lit l] l
[:var x]
(match (get unification x)
([:ellipsis _] :as p)
(strip-ellipsis p ellipsis-depth)
(_ :guard nil?)
#_(throw (ex-info "unbound" {:symbol x}))
x ;; unhygenic but it's demo }:)
p p)
[:list ts]
(do #_ #dbg (+ 0 0)
(->> (for [t ts]
(match t
[:ellipsis t*] (transcribe* (inc ellipsis-depth) unification t*)
:else [(transcribe* ellipsis-depth unification t)]))
(apply concat))))))
(defn transcribe [unification template]
(transcribe* 0 unification (s/conform ::template template)))
(comment
(transcribe-transformer scheme-and '(and 1 2)))
(defn transcribe-transformer [trans datum]
(some (fn [{:keys [pattern template]}]
(when-some [unification (unify* pattern datum)]
(let [r (transcribe* unification template)]
(assert r)
r)))
(:rules trans)))
(defn symtable-for-env [env]
(into {}
(for [[[_ x] _] env]
+106
View File
@@ -0,0 +1,106 @@
(ns unhygienic
(:require [clojure.core.match :refer [match]]
[clojure.spec.alpha :as s]
[expand]))
(defn- merge-unify-with
([f] {})
([f a] a)
([f a b] (and a b (merge-with f a b)))
([f a b & xs] (reduce #(merge-unify-with f %1 %2) (cons a (cons b xs)))))
(defn- merge-unify [& xs]
(apply merge-unify-with (fn [_ x] x) xs))
(defn- unify* [pattern datum]
(match [pattern datum]
[[:wildcard _] _] {}
[[:var x] _] {x datum}
[[:list {:leading leading
:trailing nil
:ellipsis ellipsis}]
(_ :guard seq?)]
(let [[leading-datum ellipsis-datum] (split-at (count leading) datum)]
(merge-unify
(apply merge-unify (map #(unify* %1 %2)
leading
leading-datum))
(some->> ellipsis-datum
(map #(when-some [r (unify* ellipsis %)]
(->> r
(map (fn [[k v]] [k (list v)]))
(into {}))))
(apply merge-unify-with concat)
(map (fn [[k v]]
[k [:ellipsis v]]))
(into {}))))
[[:list {:leading leading}]
(_ :guard seq?)]
(when (= (count datum)
(count leading))
(->> (map #(unify* %1 %2) leading datum)
(apply merge-unify)))
;; no match
:else nil))
(defn unify [pattern datum]
(unify* (s/conform :expand/pattern pattern) datum))
(comment
(transcribe (unify '((a ...) ...)
'((1 2) (3 4) (5 6)))
'(begin (a ...) ...))
(strip-ellipsis
'[:ellipsis ([:ellipsis (1 2)] [:ellipsis (3 4)] [:ellipsis (5 6)])]
2))
(defn- strip-ellipsis [unif ellipsis-depth]
(match unif
[:ellipsis p]
(if (< 0 ellipsis-depth)
(map #(strip-ellipsis % (dec ellipsis-depth)) p)
(throw (ex-info "나쁜 점점점" {})))
:else unif))
(defn- transcribe*
([unification template]
(transcribe* 0 unification template))
([ellipsis-depth unification template]
(match template
[:lit l] l
[:var x]
(match (get unification x)
([:ellipsis _] :as p)
(strip-ellipsis p ellipsis-depth)
;; unhygenic but it's demo }:)
(_ :guard nil?) x
p p)
[:list ts]
(->> (for [t ts]
(match t
[:ellipsis t*] (transcribe* (inc ellipsis-depth) unification t*)
:else [(transcribe* ellipsis-depth unification t)]))
(apply concat)))))
(defn transcribe [unification template]
(transcribe* 0 unification (s/conform :expand/template template)))
(comment
(transcribe-transformer scheme-and '(and 1 2)))
(defn transcribe-transformer [trans datum]
(some (fn [{:keys [pattern template]}]
(when-some [unification (unify* pattern datum)]
(let [r (transcribe* unification template)]
(assert r)
r)))
(:rules trans)))