I am a beginner in PDDL and currently want to build a Project, that allows a rover to autonomously act on mars. Basically, the rover should have a battery.
Eg. rover can increase the amount by charging at a waypoint (+10 per action) and the percentage will be decreased a -> b (-15).
It should be modeled rather simple so there has to be no decrease over time, I just want to define in the init sth. like:
when it travels from a to b amount decreased by 10, from b to c by -10 and from a to c -25...
this is my domain file currently:
(define (domain rover)
(:requirements :fluents)
(:types LOCATION - Obj
ROVER - Obj)
(:constants )
(:predicates (path ?r - ROVER ?l1 ?l2 - LOCATION)
(at ?r - ROVER ?l - LOCATION)
)
(:functions
(battery-amount)
;(battery-capacity)
)
(:action move
:parameters (?r - ROVER ?from - LOCATION ?to - LOCATION)
:precondition (and (at ?r ?from) (path ?r ?from ?to) (> (battery-amount) 90))
:effect (and (at ?r ?to) (not (at ?r ?from))
(decrease (battery-amount) 10)
)
)
)
this is the Problem:
(define (problem roverprob1)
(:domain rover)
(:objects
r0 - ROVER
l0 l1 l2 l3 l4 - LOCATION)
(:init (at r0 l1) (= (battery-amount) 100)
(path r0 l3 l0) (path r0 l0 l3) (path r0 l3 l1)
(path r0 l1 l3) (path r0 l1 l2) (path r0 l2 l1)
(path r0 l3 l4) (path r0 l4 l3)
)
(:goal (and (at r0 l4)))
)
My idea was that my battery-amount should be a function in the domain, Its initial value is set in Problem with 100 and to start with every action move should decrease the amount by 10.
to verify the results I implemented a precondition to the action move which should check if the amount is greater than 90.
My rover has to move in two steps in order to get to Location l4. so he should not be able to make it to l4.
Interestingly enough the Editor still finds a way to solve the problem. It is the same solution that I would get without the battery amount.
It seems to me, that he does not update the value and I have no idea why ^^
thank you in advance for any help or suggestions!
UPDATE
I dug further into the problem and got myself the PDDL expansion for VSCode.
You can view the current state here: current state
If I take a look at the visual output that vs code provides I noticed the following:
(:init
(at r0 l1)
(= (fuel-level r0) 90)...)
when the rover has enough energy to drive along the path, the graph for the fuel level shows the following:
but when I change the init value, so the rover should not be able to get to the goal waypoint
(:init
(at r0 l1)
(= (fuel-level r0) 50)...)
the fuel used graph does look very different:
the graph is now a line that seems to be at 0 the whole time.
So I am thinking, that the planer knows that the fuel is not enough and therefore treats it as 0 but the precondition does not trigger.
I would expect an output like: Goal can be simplified to false or sth. like that.
I need this precondition to be working because eventually, I want the rover to recharge its battery when he determines that he cant make a path with his fuel level...
Related
I made a small repro for this issue using only lisp.
file1.lisp :-
(defpackage :my_package
(:use :cl))
(in-package :my_package)
(defun subscribe (x) (print x)(terpri))
(export '(subscribe))
(in-package :cl-user)
file2.lisp :-
(defun loader ()
(load "file1.lisp")
(my_package:subscribe "hello"))
(loader)
Now, running this gives the same error :-
sbcl --load file2.lisp
This is SBCL 2.1.11.debian, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
debugger invoked on a SB-C::INPUT-ERROR-IN-LOAD in thread
#<THREAD "main thread" RUNNING {1001834103}>:
READ error during LOAD:
Package MY_PACKAGE does not exist.
Line: 3, Column: 22, File-Position: 59
Stream: #<SB-INT:FORM-TRACKING-STREAM for "file /home/omkarwagh/swarajya/scratch/file2.lisp" {10009BF613}>
Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [ABORT ] Abort loading file "/home/omkarwagh/swarajya/scratch/file2.lisp".
1: [CONTINUE] Ignore runtime option --load "file2.lisp".
2: Skip rest of --eval and --load options.
3: Skip to toplevel READ/EVAL/PRINT loop.
4: [EXIT ] Exit SBCL (calling #'EXIT, killing the process).
(SB-C:COMPILER-ERROR SB-C::INPUT-ERROR-IN-LOAD :CONDITION #<SB-INT:SIMPLE-READER-PACKAGE-ERROR "Package ~A does not exist." {10018375A3}> :STREAM #<SB-INT:FORM-TRACKING-STREAM for "file /home/omkarwagh/swarajya/scratch/file2.lisp" {10009BF613}>)
4
I guess that the problem is that we don't know the package at read time because the relevant file has not been loaded yet.
So the question is, what is the recommended practice in this case?
Original question
I have a roswell script that I've attached below. I have an asdf system called "my_system" which has only one module with one file that contains only one package called "my_package".
Somehow, the asdf system is being loaded but when I try to actually use any of the functions in it, then it fails with an error saying that "my_package" is not found
#!/bin/sh
#|-*- mode:lisp -*-|#
#|
exec ros -Q -- $0 $(readlink -f $(dirname $(readlink -f $0)))/asdf.conf "$#"
|#
(progn ;;init forms
(ros:ensure-asdf)
#+quicklisp(ql:quickload '() :silent t)
)
(defpackage :ros.script.test.3880638094
(:use :cl))
(in-package :ros.script.test.3880638094)
(require "asdf")
;(asdf:load-system "my_system")
;(print #'my_package:subscribe)
(defun main (mydir &rest argv)
(declare (ignorable argv))
(asdf:initialize-source-registry `(:source-registry :inherit-configuration (:include ,mydir)))
(asdf:load-system "my_system")
(sleep 0.2)
(print "here3")(terpri)
(print (list-all-packages))
(do-external-symbols (s (find-package :my_package)) (print s))
(print #'my_package::subscribe)(terpri)
)
;;; vim: set ft=lisp lisp:
The error is :-
Unhandled SB-C::INPUT-ERROR-IN-LOAD in thread #<SB-THREAD:THREAD "main thread" RUNNING
{1004460113}>:
READ error during LOAD:
Package MY_PACKAGE does not exist.
However, if I comment out this line :-
(print #'my_package::subscribe)(terpri)
I do in fact, see the package in the list of packages as well as the symbol in question :-
#<PACKAGE "MY_PACKAGE">
MY_PACKAGE:SUBSCRIBE
As you said, the error is signalled because the package does not exist at the read time (when the form is read as text and translated to symbols).
The most straightforward option to change the code above this is to create the symbol when function is executed, e.g., (funcall (intern "SUBSCRIBE" 'my-package)). Variant of this (using read-from-string instead of intern) can be seen in the Swank or Slynk loader.
If you use asdf (which is implied in your question), you should probably use uiop to do this for you - see uiop:symbol-call. For example, documented way to define test-op is with
:perform (test-op (o c) (symbol-call :fiveam '#:run! :foobar)))
However, most libraries structure files in such a way that this issue does not arise - the file1.lisp would be loaded before file2.lisp (e.g., using asdf system definition).
I'm writing a disassembler which is 95% complete but can't find the bitwise layouts for a couple of instructions. I have built them using both as/ld and FASMARM and they work fine on an ancient RPi emulator under "-mfpu=vfpv2 -mfloat-abi=hard".
vmov r2,r3,d0 -> EC532B10h == 0b1110_1100_0101_0011_0010_1011_0001_0000
vmov d0,r1,r2 -> EC421B10h == 0b1110_1100_0100_0010_0001_1011_0001_0000
I assume they behave as (FMRDH+FMRDL) and (FMDHR+FMDLR) rolled into one respectively.
I could of course take a blind stab and invent new (pre-UAL style) names, but...
As always, sigh, right in front of me face..
fmdrr https://developer.arm.com/documentation/ddi0301/h/vfp-programmer-s-model/armv5te-coprocessor-extensions/fmdrr?lang=en
fmrrd https://developer.arm.com/documentation/ddi0301/h/vfp-programmer-s-model/armv5te-coprocessor-extensions/fmrrd
They are indeed missing from DDI 0100E, but that's no excuse!
I want to use a timer to periodically print info to the repl (and do some other things).
SBCL 2.0.1
Emacs 26.1
sly 1.0.0-beta-3
(I can't create a sly tag...)
in sly-repl:
(defvar *timer* (make-timer (lambda ()
(write-line ".")
(force-output))))
(schedule-timer *timer* 2 :repeat-interval 1)`
and works fine - after 2 seconds, "." is printed
in timer-test.lisp:
(defvar *timer* (make-timer (lambda ()
(write-line ".")
(force-output))))
(schedule-timer *timer* 2 :repeat-interval 1)`
compiles fine
when I execute the schedule-timer form, the REPL tells me:
Timer #<TIMER {1002C5EB33}> failed to interrupt thread #<SB-THREAD:THREAD "slynk-worker" FINISHED values: T {1002C3DFA3}>.
I don't know enough about threads in SBCL to sort this out. Is there a simple way to get a scheduled timer (in a file) to output to the REPL?
with thanks for your help.
Here is a version of your code which tries to use some SWANK functionality to find out what the REPL thread is and schedule the timer in that thread. Note that this won't work with SLY as far as I can tell because SLY has different package names at least. However it may provide a clue and it's too long to be a comment.
Note also that I don't know if this is the right way of finding the REPL thread, or if the REPL thread actually persists for any length of time.
If repl-thread-maybe fails to find a candidate thread, it returns t, which causes make-timer to run the timer in its own thread. This is safe I think, but will mean that any output from the timer (assuming that's what you are after) goes somewhere other than the REPL.
Anyway, here it is for what it's worth
;;;;
;;;
(in-package :cl-user)
#-(and SBCL SWANK)
(eval-when (:compile-toplevel :load-toplevel :execute)
(error "Not SBCL / not SWANK"))
(defun repl-thread-maybe (&key (repl-thread-name "repl-thread")
(fallback-value t))
;; I have no idea if this is the right way to find the REPL thread,
;; but it kind of works.
(or (find-if (lambda (thread)
(string-equal (swank/backend:thread-name thread)
repl-thread-name))
(swank/backend:all-threads))
fallback-value))
(defparameter *timer* (make-timer (lambda ()
(write-line ".")
(force-output))
:thread (repl-thread-maybe)))
(schedule-timer *timer* 2 :repeat-interval 1)
After many years away from programming, I've decided to take it up again for fun, and finding myself enjoying it quite a lot. In the process of finding things to code, I've found this data which is openly available from Network Rail in the United Kingdom.
Among other things, you can obtain schedule data, which is a list of all train, bus and ferry journeys.
A schedule record for a train journey might look like this:
BSNY819581902281902280001000 PEE5A99 122112002 EMU390 125
BX VTY
LOMNCRPIC 2131 00008 FL TB
LIARDWCKJ 2133 00000000
LISLDLJN 2134H00000000 SL H
LIHTNOJN 2138 00000000 FL 1H
LISTKP 2140H000000002 SL
LISTKPE1 2141H00000000
LIADSWDRD 2142H00000000
LICHDH 2143 000000002
LIWLMSL 2146 000000004 1
LIALDEDGE 2148 00000000 1 3
LISBCH 2200 000000001 FL
LICREWSBG 2203 00000000
LICREWUML 2204 00000000
LICREWE 2206 000000001 FL H
LICREWBHJ 2207H00000000 1
LIMADELEY 2212 00000000 FL FL 5H
LINTNB 2222H00000000 FL FL
LISTAFFDJ 2226H00000000 SL
LISTAFFRD 2228H2231H 000000004 SL SL A C
LISTAFTVJ 2233 00000000
LIPNKRDG 2236H00000000 1 1
LIBSBYJN 2244 00000000
LIPBLJWM 2248 00000000
LIDRLSTNJ 2251H00000000
LIBSCTSTA 2252H00000000 1
LIPRYBRNJ 2257 00000000 7
LIASTON 2306H000000002
LISTECHFD 2311H00000000
LIBHAMINT 2315 000000004
LIBKSWELL 2318H00000000 1H
LICOVNTRY 2324 000000001 2 3
LIRUGBTVJ 2336 00000000 UNL 3
LIRUGBY 2340 000000005 UNLUNL 1H
LIHMTNJ 2343 00000000 1H
LIDVNTYNJ 2346H00000000
LILNGBKBY 2351 00000000 1 1
LINMPTN 0001H000000001 6
LIHANSLPJ 0016 00000000 SL
LIMKNSCEN 0021 000000001 SL SL
LIBLTCHLY 0023 000000004 SL SL 5 1H
LILEDBRNJ 0036 00000000 SL SL 2
LITRING 0042 000000002 SL SL 2H
LIBONENDJ 0048H00000000 SL SL 1H
LIWATFDJ 0056 000000009 SL SL 1H
LIHROW 0101H000000006 SL SL 3
LIWMBY 0107H000000006 CL
LTWMBYICD 0117H0000 TF
tl;dr the first two lines describe what type of train is running, when it runs, how fast, etc. The other lines describe the points the train will pass, and what time they are expected to do so. The main takeaway is that each record has a different length depending on the journey.
When I saw this, I thought "This would be a great thing to try and mess around with in COBOL." I went to polytech and learned PASCAL and COBOL, but only had to deal with files with a consistent length and consistent data, not something like this.
I spent a couple of hours trying to find some sort of answer to this on Google, but nothing really showed, hence my asking.
Just for reference, I have managed to do this in GW-BASIC, and could do it in elementary Python if needed, but COBOL, being what it is, is a whole different kettle of fish.
Is it possible to read something like this in to COBOL without having to resort to witchcraft, or is it just in the "too hard" basket? I'm only doing this for fun, so it's really no big deal.
Any responses or feedback would be most welcome.
Many thanks,
Joseph.
Yes it is possible. For the file use Line Sequential
The file definition
select lineseq assign to "lineseq.dat"
organization is line sequential.
To split the lines up use UNSTRING. i.e.
UNSTRING in-line
DELIMITED BY SPACES
into item-1, item-2, item-3
END-UNSTRING
It is probably easier to do in languages like python
Actually (after reformatting the question) I think COBOL is
perfect for this job as the data is fixed-length (may came out of COBOL, too...)
define the file (line-sequential may not even be needed if it contains, like your post even trailing spaces; but as this may change, line-sequential would be fine)
OPEN INPUT file, READ until end of file
put the complete record read into a local record with defined sub-fields and just access the data from the sub-fields, after validating (the file may be broken for many reasons)
Depending on the amount of lines in that data you may either process the records direct, move them to a table (have a look at OCCURS), or WRITE them to another file (likely and INDEXED with multiple KEY definitions)
To expand on #Simon Sobisch's answer.
Looking at the data, and trying to work it out, I can see these things.
Top two lines as you say are the type of train and that.
Then you have a line starting LO which must be the start of the journey. The next 7 characters would be the station, with MNCRPIC being presumably "Manchester Piccadily". Then there's a space, then four digits which would be a time.
Then you have a load of lines starting LI which are intermediate points. Some of those have a "H" after the time, others don't. This will be a problem if you're going to do UNSTRING DELIMITED BY SPACE. I'm going to presume that H means Halt.
LISTAFFRD 2228H2231H 000000004 SL SL A C
is an odd looking line.
At the end we have LT which is the end of the journey, arriving at WMBYICD at 0117.
01 TRAIN-SCHEDULE.
03 RECORD-TYPE PIC XX.
88 JOURNEY-START VALUE 'LO'.
88 JOURNEY-INTERMEDIATE VALUE 'LI'.
88 JOURNEY-TERMINATE VALUE 'LT'.
03 TRAIN-STATION PIC X(7).
03 FILLER PIC X(11).
03 TRAIN-TIME.
05 TRAIN-TIME-HH PIC 99.
05 TRAIN-TIME-MM PIC 99.
03 TRAIN-HALT-FLAG PIC X.
88 TRAIN-STOPS-HERE VALUE 'H'.
And so on.
COBOL input files can be VARIABLE or FIXED. If it is variable, the first positions will be the number of cols of the row.
Here you have the information at IBM official webpage.
Processing Files with Variable Length Records
I would like to implement a "tail -f" like behavior in Racket. That is, I would like to read from a file, and when I hit the end, be able making something like a "blocking" (read-line file), that shall return when some other process appends a line to file.
I tried synchronizing with (read-line-evt file) but, if I am at the end of file, instead of blocking until other data is available, it returns immediately.
Is there a way to do it?
I don't think that you have any way to avoid polling the file.
Note that all of Racket's input functions consider eof a value that should be returned when it reaches the end of the input stream -- so all of the events immediately return that when the end is reached. At least I don't see anything that looks like a "wait until some input is ready, not eof".
In any case, you also have the ffi, if you know about some system call that triggers a callback instead of polling the file. AFAICT, the linux source code for tail uses inotify, so you might be able to use an old package that interfaces that from racket called mzfam. (But it's pretty old and might need some update work.)
I don't know when Racket added file system change events, but I suspect it was since this question was asked many years ago. Now you can wait on such an event and see if you can read another line (It's not fine grained enough to tell specifically that more data was appended to the file, just that something changed about it.)
An example of a basic tail -f like program to demonstrate file-system-change-evt:
;;; tail.rkt
#lang racket/base
(require racket/list racket/port)
;;; Some utility functions and macros
;; Like take but return the list if it's less than n elements long
;; instead of raising an error
(define (take* list n)
(with-handlers ([exn:fail:contract? (lambda (e) list)])
(take list n)))
;; Repeat body forever until a break is received
(define-syntax-rule (forever body ...)
(with-handlers ([exn:break? (lambda (e) (void))])
(let loop ()
body ...
(loop))))
;; Display the last N lines of a file. Could be more efficient, but
;; this part's not the point...
(define (display-last-lines port n)
(for-each displayln
(reverse
(for/fold ([lines '()])
([line (in-lines port)])
(take* (cons line lines) n)))))
;; Wait for the file's status to change and try to read lines when it does.
(define (follow-tail file)
(call-with-input-file file
(lambda (port)
(display-last-lines port 10)
(forever
(sync (filesystem-change-evt file))
(for ([line (in-lines port)])
(displayln line))))))
(module+ main
(unless (= (vector-length (current-command-line-arguments)) 1)
(displayln "Usage: racket tail.rkt FILENAME" (current-error-port))
(exit 1))
(follow-tail (string->path (vector-ref (current-command-line-arguments) 0))))
After being inspired by this question and Eli's mention of inotify in his answer, and seeing that there still wasn't a Racket package to provide access to it (I think the standard file system change code uses it internally, but it's not exposed at any low level to users), I wrote it myself. A version of the core tail function from above using it:
(require inotify)
(define (follow-tail file)
(call-with-input-file file
(lambda (port)
(display-last-lines port 10)
(call-with-inotify-instance
`((,file (IN_MODIFY)))
(lambda (inotify wds)
(forever
(sync inotify)
(for ([line (in-lines port)])
(displayln line))))))))