#+TITLE: World of shouting the first #+Author: screwlisp * tl;dr :read:this: This story is everything important: #+BEGIN_EXAMPLE ,*** Story ,#+CALL: create-walk-eg() ,#+RESULTS: : #<PACKAGE "WALK-EG"> ,#+call: define-walking() ,#+RESULTS: | WALK-EG::WALK-TO-STUDY | ,#+call: imagine-walking() ,#+RESULTS: : STUDY-UNLOCKED be silent for thou art T : IN-HALLWAY be silent for thou art T : : (T T) Since all are silent, I walk into the study : BEHOLD : G841::IN-HALLWAY: NIL : G841::IN-STUDY: T ,#+call: sabotage-shoelaces() ,#+RESULTS: | WALK-EG::WALK-TO-STUDY | ,#+call: imagine-walking() ,#+RESULTS: : STUDY-UNLOCKED be silent for thou art T : SHOELACES-CORRECT was NIL : IN-HALLWAY be silent for thou art T : : (T NIL T) Since I am forebidden to walk into the study, I will stumble. : BEHOLD : G842::IN-HALLWAY: T : G842::IN-STUDY: NIL #+END_EXAMPLE Alright! This was an ode to @flying_saceur telling me about the world of shouting. I ended up having to scribble INTERN everywhere and use SET rather than setf. It's very drafty. If you wanted to execute this, before hand (in the slime session) one must execute everything in - Connect to slime - Trivial sensitivities - World of Shouting after which one would jump to *** story at the end and C-c C-c each step in turn. I think my biggest difference to erisa here (okay, there are many) is that erisa uses macro-characters to make s-expressions with different brackets ==({[]}}== having conventional logic meanings and underlying behaviours, whereas I wanted to use common lisp (and clim2 eventually) intrinsics, but understand them as having logic meanings. For example symbols having a symbol-value are understood to be generalised boolean predicates. Ie I would (defvar *foo* t) rather than store an s-expression like (*foo* t). * Background I read erisa's draft AICA-1-CORE which outlines some aspects of their technocognitive software individuals. After this, @flyingsaucer wrote a series of mastodon toots introducing me to the World Of Shouting after trying to figure out where my understanding of computer reasoning had gone wrong (after three attempts at understanding where I'd gotten myself to). We're just going to like, do this. * Warning: Contains codes in lisp. Using my clim2 slime orgmode idiom. ** Connect to slime *** org babel do load languages. #+begin_src elisp :results none (org-babel-do-load-languages 'org-babel-load-languages '((lisp . t))) #+end_src *** clim connect (featuring clim) #+name: start-slime #+begin_src elisp (eshell) (insert "sbcl --dynamic-space-size 2560 --load ~/common-lisp/slime*/start-swank.lisp --eval '(require :mcclim)' &") (eshell-send-input) (switch-to-prev-buffer) #+end_src #+RESULTS: start-slime : #<buffer first-take.org> *** slime-connect #+begin_src elisp (slime-connect "localhost" "4005") #+end_src #+RESULTS: : #<process SLIME Lisp> ** Trivial sensitivities Find variables in package sensitive to a command name = action = verb. *** define :trivial-sensitivities #+begin_src lisp (uiop:define-package :trivial-sensitivities (:export #:add-sensitivity #:remove-sensitivity #:find-sensitive) (:nicknames :tries)) #+end_src #+RESULTS: : #<PACKAGE "TRIVIAL-SENSITIVITIES"> *** Trivial sensitivities defuns **** add-sensitivity #+begin_src lisp (in-package :tries) (defun add-sensitivity (watches watched) (setf (getf (symbol-plist watches) :sensitivities) (append (getf (symbol-plist watches) :sensitivities) (and watched `(,watched))))) #+end_src #+RESULTS: : ADD-SENSITIVITY **** remove-sensitipvity #+begin_src lisp (in-package :tries) (defun remove-sensitivity (from remove) (setf (getf (symbol-plist watches) :sensitivities) (delete remove (getf (symbol-plist watches) :sensitivities)))) #+end_src #+RESULTS: : REMOVE-SENSITIVITY **** find-sensitive #+begin_src lisp (in-package :Tries) (defun find-sensitive (symbol &rest packages) (with-package-iterator (mname packages :internal :external) (loop for (ret sym) = (multiple-value-call 'list (mname)) while ret when (member (symbol-name symbol) (add-sensitivity sym nil) :key 'symbol-name :test 'equal) nconcing (and (boundp sym) (list sym))))) #+end_src #+RESULTS: : FIND-SENSITIVE ** The world of shouting *** Define :world-of-shouting **** desc - World is a package - All symbols having a symbol-value are generalised booleans - Check ==(documentation 'my-symbol 'variable)== for meaning hence no behavioural information is visible from the package. This information is stored as slots of an instance of ==clim:application-frame== probably named ==package:me==. Note that this would be bring-up-able through ==(clim:find-package 'package:me)==. Currently no use is made of ==(symbol-function 'symbol)==, though this is anticipated. In particular, variables might have associated functions that are run related to when that symbol was checked (as a result of ==find-sensitive==. Actions are stored in the ==command-table== of said ==package:me== application frame. This is the canonical reference to the actions. ==Clim== commands exist in a few ways, similar to erisa's actions/commands/verbs. There are possible commands in the command-table. A command in the command-table can be instantiated, these instantiations having the ==clim:presentation-type== of command. Instantiations of commands can then be called. (Factcheck self). Episodes, real or imagined are formed and stored somewhere within the ==episodes== slot of the package's application-frame. Episodes are anticipated to have enough information to create a ==state-of-the-world== representing at least one real or imagined time. I guess an episode consists of something like a list of values to set to initially set the world, and an action sequence that would then take place (presumably over time) in aforesaid world. ==:world-of-shouting== contains machinery to help with this. Note that knowledge storing packages should probably not ==:use== ==:cl==, so the ==uiop:define-package== would need to override the default by specifying ==(:use)==. **** src #+begin_src lisp (uiop:define-package :world-of-shouting (:export #:make-episode-from #:package-episode) (:import-from :tries :clim :climlisp) (:nicknames :wos)) #+end_src #+RESULTS: : #<PACKAGE "WORLD-OF-SHOUTING"> **** make-episode-from I guess symbol is a verb = clim command on [some] ==package::me== application frame's ==command-table==. I guess by definition the #+begin_src lisp (in-package :wos) (defun make-episode-from (symbol-list &rest packages) " " (list symbol-list (loop for symbol in symbol-list nconcing (let* ((Symbols (apply 'tries:find-sensitive symbol packages)) (values (mapcar (lambda (x) (and (boundp x) (symbol-value x))) symbols))) (pairlis symbols values))))) #+end_src #+RESULTS: : MAKE-EPISODE-FROM **** package-episode #+begin_src lisp (in-package :Wos) (defun package-episode (episode &optional (package-name nil) &aux (package-name (or package-name (gensym)))) (loop initially (unless (find-package package-name) (eval `(uiop:define-package ,package-name (:use)))) for cons in (cadr episode) for symb = (car cons) for valu = (cdr cons) for inte = (intern (symbol-name symb) package-name) do (set inte valu) finally (return (find-package package-name)))) #+end_src #+RESULTS: : PACKAGE-EPISODE *** Try and use :wos **** Def some packages. #+begin_src lisp (uiop:define-package eg-starter-1 (:use)) (uiop:define-package eg-starter-2 (:use)) #+end_src #+RESULTS: : #<PACKAGE "EG-STARTER-2"> **** def some vars. #+begin_src lisp (defvar eg-starter-1::a t) (defvar eg-starter-1::b nil) (defvar eg-starter-2::c t) (defvar eg-starter-2::d nil) #+end_src #+RESULTS: : EG-STARTER-2::D **** Add some sensitivities. #+begin_src lisp (loop for var in '(eg-starter-1::a eg-starter-1::b eg-starter-2::c) do (tries:add-sensitivity var 'foo)) (tries:add-sensitivity 'eg-starter-2::d 'bar) #+end_src #+RESULTS: | BAR | **** try find-sensitive #+begin_src lisp (tries:find-sensitive 'foo :eg-starter-1) #+end_src #+RESULTS: | EG-STARTER-1::B | EG-STARTER-1::A | **** try make-episode-from #+name: make-ep-eg #+begin_src lisp (wos:make-episode-from '(foo bar) :eg-starter-1 :eg-starter-2) #+end_src #+RESULTS: make-ep-eg | FOO | BAR | | | | (EG-STARTER-2::C . T) | (EG-STARTER-1::A . T) | (EG-STARTER-1::B) | (EG-STARTER-2::D) | **** try package-episode #+name: pkg-ep #+begin_src lisp :var episode=make-ep-eg() :Cache yes (wos:package-episode episode) #+end_src #+RESULTS: : #<PACKAGE "G791"> **** What's in that package? #+begin_src lisp :results output verbatim :var pkg="G791" (with-package-iterator (mname pkg :internal :external) (loop for (ret var) = (multiple-value-call 'list (mname)) while ret do (print var) (princ #\space) (princ (symbol-value var)))) #+end_src #+RESULTS: : : G791::D NIL : G791::C T : G791::B NIL : G791::A T ** But can we fail to walk into the study? *** walk-to-study **** Some predicates. A bit contrived, but how much more org-file do you want to read today? #+name: create-walk-eg #+begin_src lisp (wos:package-episode '(() ((in-hallway . t) (study-unlocked . t) (in-study . nil))) :walk-eg) #+end_src #+RESULTS: create-walk-eg : #<PACKAGE "WALK-EG"> *** function #+name: define-walking #+begin_src lisp (defun walk-eg::walk-to-study (from to) (set from nil) (set to t)) (tries:add-sensitivity 'walk-eg::in-hallway 'walk-eg::walk-to-study) (tries:add-sensitivity 'walk-eg::study-unlocked 'walk-eg::walk-to-study) #+end_src #+RESULTS: define-walking | WALK-EG::WALK-TO-STUDY | *** Imagine walking to the study. #+name: imagine-walking #+begin_src lisp :results output verbatim (let* ((episode (wos:make-episode-from '(walk-eg::walk-to-study) :walk-eg)) (pkg (wos:package-episode episode))) (with-package-iterator (mname `(,pkg) :internal) (let ((vals (loop for (ret var) = (multiple-value-call 'list (mname)) for val = (and ret (symbol-value var)) while ret when (boundp var) collect val into vals unless val do (format t "~a was ~a~%" var val) when val do (format t "~a be silent for thou art ~a~%" var val) finally (return vals)))) (print vals) (if (not (search '(nil) vals)) (progn (format t "Since all are silent, I walk into the study") (walk-eg::walk-to-study (intern "IN-HALLWAY" pkg) (intern "IN-STUDY" pkg))) (format t "Since I am forebidden to walk into the study, I will stumble.")))) (terpri) (format t "~a~%" 'behold) (format t "~s: ~a~%" (intern "IN-HALLWAY" pkg) (symbol-value (intern "IN-HALLWAY" pkg))) (format t "~s: ~a~%" (intern "IN-STUDY" pkg) (and (boundp (intern "IN-STUDY" pkg)) (symbol-value (intern "IN-STUDY" pkg))))) #+end_src #+RESULTS: imagine-walking : STUDY-UNLOCKED be silent for thou art T : IN-HALLWAY be silent for thou art T : : (T T) Since all are silent, I walk into the study : BEHOLD : G840::IN-HALLWAY: NIL : G840::IN-STUDY: T *** Add an unexpected restriction on walking #+name: sabotage-shoelaces #+begin_src lisp (defvar walk-eg::shoelaces-correct nil) (tries:add-sensitivity 'walk-eg::shoelaces-correct 'walk-eg::walk-to-study) #+end_src #+RESULTS: | WALK-EG::WALK-TO-STUDY | *** Story #+CALL: create-walk-eg() #+RESULTS: : #<PACKAGE "WALK-EG"> #+call: define-walking() #+RESULTS: | WALK-EG::WALK-TO-STUDY | #+call: imagine-walking() #+RESULTS: : STUDY-UNLOCKED be silent for thou art T : IN-HALLWAY be silent for thou art T : : (T T) Since all are silent, I walk into the study : BEHOLD : G841::IN-HALLWAY: NIL : G841::IN-STUDY: T #+call: sabotage-shoelaces() #+RESULTS: | WALK-EG::WALK-TO-STUDY | #+call: imagine-walking() #+RESULTS: : STUDY-UNLOCKED be silent for thou art T : SHOELACES-CORRECT was NIL : IN-HALLWAY be silent for thou art T : : (T NIL T) Since I am forebidden to walk into the study, I will stumble. : BEHOLD : G842::IN-HALLWAY: T : G842::IN-STUDY: NIL