Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
tutorials:advanced:task_trees [2015/07/08 14:08] – [Changing parameters with plan transformation] mpomarlantutorials:advanced:task_trees [2020/09/17 14:09] (current) – [Plan transformations: task trees, code replacement, and serialization] gkazhoya
Line 1: Line 1:
 ====== Plan transformations: task trees, code replacement, and serialization ====== ====== Plan transformations: task trees, code replacement, and serialization ======
 +
 +**Disclaimer:** the most up to date overview of plan transformations you can find in README.md of ''cram_plan_transformation'' package (''CRAM_REPO/cram_3d_world/cram_plan_transformation/README.md''). The tutorial below is out of date and has not be maintained, unfortunately, but you might still find some useful explanations there. Otherwise, stick to the README.
  
 **Description:** this tutorial is aimed at CRAM developers, and its purpose is to present an in-development aspect of CRAM. It is less a proper tutorial and more documentation for work in progress. Expect content to change. It contains an intro to task trees, a data structure used by CRAM functions (note: this has existed in CRAM for a while and will not change). It also describes code replacement (also long existing), failure handling through code replacement (new), and serialization of task trees and functions (new). **Description:** this tutorial is aimed at CRAM developers, and its purpose is to present an in-development aspect of CRAM. It is less a proper tutorial and more documentation for work in progress. Expect content to change. It contains an intro to task trees, a data structure used by CRAM functions (note: this has existed in CRAM for a while and will not change). It also describes code replacement (also long existing), failure handling through code replacement (new), and serialization of task trees and functions (new).
Line 284: Line 286:
 <code lisp> <code lisp>
 (swank:operate-on-system-for-emacs "cram-projection" (quote load-op)) (swank:operate-on-system-for-emacs "cram-projection" (quote load-op))
 +(in-package :cpl-impl)
 (cram-projection:define-projection-environment example-env) (cram-projection:define-projection-environment example-env)
-(in-package :cpl-impl) 
  
 (def-top-level-cram-function tryprj ()  (def-top-level-cram-function tryprj () 
Line 356: Line 358:
   (format T "Inside example-ptr.~%")   (format T "Inside example-ptr.~%")
   (format T "Received arguments ~a~%" args)   (format T "Received arguments ~a~%" args)
-  (format T "PTR parameter is (~a)~%Will now fail, so as to trigger plan transformation.~%" (cpl-impl:get-ptr-parameter))+  (format T "PTR parameter is (~a)~%Will now fail, so as to trigger plan transformation.~%" P)
   (cpl:fail 'cpl-impl:plan-failure))   (cpl:fail 'cpl-impl:plan-failure))
  
-(defun compatible-ptr (&rest args)+(defun compatible-ptr (&rest args)
   (format T "Inside compatible-ptr.~%")   (format T "Inside compatible-ptr.~%")
   (format T "Received arguments ~a~%" args)   (format T "Received arguments ~a~%" args)
-  (format T "PTR parameter is (~a)~%Done!~%" (cpl-impl:get-ptr-parameter)))+  (format T "PTR parameter is (~a)~%Done!~%" P))
                        
 (cpl-impl:def-top-level-cram-function try-ptr () (cpl-impl:def-top-level-cram-function try-ptr ()
Line 378: Line 380:
 Of these, example-ptr is the "star" of the show. Notice that it's been defined with def-ptr-cram-function, and what that tells CRAM is that the first argument in the supplied lambda list (in this case, P) is supposed to be a "compile-time", or plan-transformation accessible, parameter. Of these, example-ptr is the "star" of the show. Notice that it's been defined with def-ptr-cram-function, and what that tells CRAM is that the first argument in the supplied lambda list (in this case, P) is supposed to be a "compile-time", or plan-transformation accessible, parameter.
  
-ptr-cram-functions are a bit peculiar. The body of the ptr-cram-function doesn't actually know the P parameter exists! So if you tried to invoke P somewhere in example-ptr'body, you would get an undefined variable warningThe reason behind this design decision was to force a ptr-cram-function to have only one way to access its compile-time parameter, and that is+ptr-cram-functions are a bit peculiar. When you call them the first time they behave like regular cram functions, and take their parameters from the ones you supplied. When you call them again (meaning, when there'a node in the task tree corresponding to the plan location you're calling them from)they ignore the first parameter in the lambda list you supply them with and replace it with the ptr-parameter stored in the task tree nodeptr-cram-functions do all this automatically; you don't need to write anything different when using them. In the example above, the ptr-cram-function uses the P parameter as if it were a usual parameter.
  
-<code lisp> +To actually change the compile time parameter in nodenotice the extra &key parameter in replace-task-code:
-(cpl-impl:get-ptr-parameter) +
-</code> +
- +
-This function will return the most recent adjustment of the compile-time parameter, which may have been changed by plan transformation. If we could also access P as regular function parameterthen we'd get the value with which it was called in the first version of the plan-- and not necessarily a value controlled through plan transformation, which defeats its purpose as a compile time parameter. +
- +
-There's a further consequence of this peculiarity of ptr-cram-functionsit implies the lambda list of a compatible replacement function must be the cdr of the lambda list that the ptr-cram-function was defined with. In the example above we have+
  
 <code lisp> <code lisp>
-(cpl-impl:def-ptr-cram-function example-ptr (P &rest args) ...) +(cpl-impl:replace-task-code '(compatible-ptr args) #'compatible-ptr code-path :ptr-parameter "Oranges")
-(defun compatible-ptr (&rest args) ...)+
 </code> </code>
  
-Finally, to actually change the compile time parameter in a node, notice the extra &key parameter in replace-task-code: +By default the :ptr-parameter to cpl-impl:replace-task-code is set to the previously effective value of ptr-parameter that is stored in the task tree node. This either the ptr-parameter in the code slot of the node (if there are no code replacements), or the ptr-parameter in the car object in the code-replacements list of the node. When a task tree node is created and a ptr-parameter is not specified, the default is nil.
- +
-<code lisp> +
-(cpl-impl:replace-task-code '(compatible-ptr args) #'compatible-ptr code-path :ptr-parameter "Another value"+
-</code>+
  
 In our example here, the compile-time parameter is a string. It can however be anything, including a struct or a list, for when you need to pass on several objects through plan transformation. In our example here, the compile-time parameter is a string. It can however be anything, including a struct or a list, for when you need to pass on several objects through plan transformation.