/* medical diagnostic system
start with ?- check.
*/
check:-
checkfor(Disease),
write('I believe you have '),
write(Disease),
nl,
undo.
/* disease to be checked */
checkfor(cold):- cold.
/* cold */
cold:-
checkSymptom(a),
checkSymptom(b),
checkSymptom(c),
nl.
askQuestion(Question):-
write('Do you have the Symptom '),
write(Question),
write('?'),
read(Reply),
nl,
( (Reply == yes ; Reply == y)
-> assert(yes(Question))
; assert(no(Question)), fail
).
:- dynamic yes/1,no/1.
checkSymptom(S) :-
( yes(S)
-> true
; ( no(S)
-> fail
; askQuestion(S)
)
).
undo :- retract(yes(_)), fail.
undo :- retract(no(_)), fail.
undo.
Related
Why does in first following case protected execution work, but in second does not?:
q)t:([]a:1 2;b:3 4);
q)#[#[cols t; ; :; `bb]; (cols t)?`b; `columnNotFound]
`a`bb
q)#[#[cols t; ; :; `cc]; (cols t)?`c; `columnNotFound] // 1. works perfectly
`columnNotFound
q)#[#[cols t; (cols t)?`c; :; `cc]; `; `columnNotFound] // 2. exception does not handled
'length
[0] #[#[cols t; (cols t)?`c; :; `cc]; `; `columnNotFound]
^
Upd:
Hmm, I suspect something after trying:
q)#[{#[cols t; (cols t)?`c; :; `cc]}; `; `columnNotFound]
`columnNotFound
The protected execution is using the argument you're supplying. The first two examples are projections but the last is not, so it fails on execution.
q){#[cols t;x;:;`bb]}(cols t)?`b
`a`bb
q){#[cols t;x;:;`cc]}(cols t)?`c / thrown into error trap
'length
[1] {#[cols t;x;:;`cc]}
^
q))\
q)#[cols t;(cols t)?`c;:;`cc] / fails on execution
'length
[0] #[cols t;(cols t)?`c;:;`cc]
^
q)
In your upd, making the # apply a function is forcing the argument in the protected execution to be used.
q){#[cols t;(cols t)?`c;:;`cc]}`
'length
[1] {#[cols t;(cols t)?`c;:;`cc]}
^
q))
I want assertion that if in current cycle signal 'a' equal to "0110"(in binary) in the next cycle signal'b'not bigger than 31(it should be between 0 and 31.it should be less than 00000000000000000000000000011111)(its width equal 32)
Can everyone help me to write assertion?!
Excuse me for my bad english.
assert property ( # (posedge clk ) (a == 32'b0110) |=> ( b > 32'd0 && b < 32'd32 ) );
assert - will set the property( assertion ) into action. The property has to be based on a clock . Choose the appropriate clock which is triggering the registers a & b in the design. Implication operator |=> indicates that the property has to be true in the next clock cycle. In this case if a equals 6, the next cycle b has to between 0 and 32 ).
In case of a failure some similar message ( based on the simulator ) will be displayed.
top.unnamed$$_0: started at ns failed at ns
Offending '((b > 0) && (b < 32))'
You can read up a basic tutorial on assertions
https://www.doulos.com/knowhow/sysverilog/tutorial/assertions/
Here is a simple program that uses the Unix module to interact with a subprocess. I just launch a cat shell command, send it a string and read it back:
#load "unix.cma";; (* Needed if you are in the toplevel *)
let () =
let sin, sout, serr = Unix.open_process_full "cat" [||] in
output_string sout "test\n";
flush sout;
input_line sin |> print_string;
flush stdout;
Unix.close_process_full (sin, sout, serr) |> ignore;;
Recently I started studying the Lwt library, and I wanted to reproduce the same functionality with it. I though that the following should have exactly the same result:
#use "topfind";; (* *)
#thread;; (* Also only for the toplevel *)
#require "lwt.simple-top";; (* *)
let () =
let open Lwt in
let process = Lwt_process.open_process_full ( "cat" , [||] ) in
Lwt_io.write_line process#stdin "test\n"
>>= ( fun () -> Lwt_io.flush process#stdin )
>>= ( fun () -> Lwt_io.read process#stdout )
>>= ( fun str -> Lwt_io.print str )
>>= ( fun () -> Lwt_io.flush Lwt_io.stdout )
|> Lwt_main.run
But it doesn't work as I expect it to -- apparently it reads and then prints an empty string.
I guess I have some fundamental confusion on how Lwt should work, but I cannot figure it out. Can someone show me how one can communicate with a subprocess using Lwt?
Use Lwt_process.shell to make a proper command, in your case, the proper command is the following:
Lwt_process.shell "cat";;
- : Lwt_process.command = ("", [|"/bin/sh"; "-c"; "cat"|])
Also, I suspect, that after you will run your program in a proper way, you will be wondering, why is your program blocking. This reason is because cat process will not finish until you write an EOF to it's input channel. That's why the Lwt_io.read call will not ever finish. A solution would be to close the stdin channel.
I recently came across an article of Manfred Mahlow from four years back which came close to solving a problem I am having. The article, "Using Glade to Create GTK+ Applications in Forth" touched upon signal handlers, stating that Forth could not be used, but only C to create them. I think my problem remains a small one, but I am stumped, I wold be very appreciative of any suggestions. Secondarily, if anyone knows how to send an email to Mr. Mahlow without using a dash in the address, I would love to hear it.
I am writing an application using the Linux version of SwiftForth to create a custom window and receive keypresses and write to that window. My goal is to implement Charles Moore's colorForth, enhanced and more user friendly. I decided to use GTK+, knowing little about it, but I have been successful but for the callbacks (signal handlers). There are only two pages of code in the whole thing, so I put it here:
\ ------------------------ COLOR FORTH -----------------------
ANEW TASK-COLORFORTH
LIBRARY /usr/lib/i386-linux-gnu/libgtk-3.so.0.1000.8
FUNCTION: gtk_window_new ( code -- addr )
FUNCTION: gtk_widget_destroy ( wptr -- )
FUNCTION: gtk_window_close ( wptr -- )
FUNCTION: gtk_widget_show ( wptr -- )
FUNCTION: gtk_init ( -- )
FUNCTION: gtk_window_set_decorated ( wptr flag -- )
FUNCTION: gtk_window_move ( wptr x y -- )
\ FUNCTION: gtk_widget_new ( n addr -- ) ( try 0 0 )
\ FUNCTION: gtk_widget_map ( wptr -- )
\ FUNCTION: gtk_widget_show_all ( wptr -- )
FUNCTION: gtk_window_get_screen ( wptr -- wgptr )
\ FUNCTION: gtk_window_present ( wptr -- )
FUNCTION: gtk_window_set_title ( wptr TitlePtr -- )
FUNCTION: gtk_window_resize ( wptr width height -- )
FUNCTION: gtk_widget_modify_bg ( wptr state cptr -- )
\ FUNCTION: gtk_widget_modify_fg ( wptr state cptr -- )
FUNCTION: gtk_widget_modify_text ( wptr state cptr -- )
FUNCTION: gtk_widget_modify_base ( wptr statre cptr -- )
FUNCTION: g_signal_connect_data ( wptr name callback data 0 0 -- )
FUNCTION: gtk_main ( -- )
FUNCTION: gtk_main_quit ( -- )
FUNCTION: gtk_widget_set_events ( wptr flag -- )
LIBRARY /usr/lib/i386-linux-gnu/libgdk-3.so.0.1000.8
FUNCTION: gdk_event_get_keyval ( eptr kptr -- )
FUNCTION: gdk_event_get_state ( eptr sptr -- )
FUNCTION: gdk_event_get_event_type ( eptr -- type ) ( requires GET.RETURN )
\ LIBRARY /usr/lib/i386-linux-gnu/libgio-2.0.so.0.4000.0
\ LIBRARY /lib/i386-linux-gnu/libglib-2.0.so.0.4000.0
\ LIBRARY /usr/lib/i386-linux-gnu/libpango-1.0.so.0.3600.3
\ LIBRARY /usr/lib/i386-linux-gnu/libatk-1.0.so.0.21009.1
\ LIBRARY /usr/lib/i386-linux-gnu/libgobject-2.0.so.0.4000.0
\ LIBRARY /usr/lib/i386-linux-gnu/libgdk_pixbuf-2.0.so.0.3000.7
VARIABLE Window-Ptr
VARIABLE Event-Ptr
VARIABLE KeyVal
VARIABLE KeyState
Z" ColorForth" VALUE Title
Z" key_press_event" VALUE Keypress-Name
Z" delete_event" VALUE Delete-Event-Name
Z" destroy" VALUE Destroy-Name
CREATE Background 0 , 0 H, 0 H, $2000 H,
CREATE Black 0 , 0 H, 0 H, 0 H,
CREATE White 0 , $E000 H, $E000 H, $8000 H,
\ ----------------------------------------------------------------
ICODE LEAVE.FALSE
EAX EAX SUB
RET
END-CODE
ICODE GET.RETURN
4 # EBP SUB
EBX 0 [EBP] MOV
EAX EBX MOV
RET
END-CODE
\ This may be the part where I am having problems
: SHUTDOWN
Window-Ptr # DUP gtk_window_close
gtk_widget_destroy
;
: CB.DELETE.EVENT ( wptr data -- false to destroy )
RDROP RDROP ( assuming 2 paramaters on Rstack and return -1 )
LEAVE.FALSE
;
: CB.DESTROY ( wptr data -- )
RDROP RDROP ( two parameters here )
gtk_main_quit
;
: CB.KEYPRESS ( wptr eptr data -- ) ( assuming 3 parameters on Rstack )
Window-Ptr # . R> . R> . R> . R# ( This for diagnosis – eventually )
SHUTDOWN ( goes to a [SWITCH )
;
: STARTUP ( -- )
Window-Ptr OFF Event-Ptr OFF
gtk_init
0 gtk_window_new ?DUP ( 0 = GTK_WINDOW_TOPLEVEL )
IF DUP Window-Ptr !
DUP 1024 gtk_widget_set_events ( 1024 for Keypress signals )
DUP Title gtk_window_set_title
DUP 1280 850 gtk_window_resize
DUP 0 gtk_window_set_decorated
DUP 0 Background gtk_widget_modify_bg
DUP Delete-Event-Name [ ' CB.DELETE.EVENT +ORIGIN ] LITERAL 0
0 0 g_signal_connect_data
DUP Destroy-Name [ ' CB.DESTROY +ORIGIN ] LITERAL 0
0 0 g_signal_connect_data
DUP Keypress-Name [ ' CB.KEYPRESS +ORIGIN ] LITERAL 0
0 0 g_signal_connect_data
gtk_widget_show
THEN
gtk_main
;
I could not use the usual g_signal_connect because I could not find it in any library I have. If it turns up, I would use it since the code is simpler. However, this code above compiles, and when I type STARTUP, it does just that. The window is there as I have specified, the signals are set, but pressing any key crashes SwiftForth with a "segmentation fault".
As you see, I am feeding the absolute address of the handler to the signal connect function. I have also tried to put that address into a variable and handing it as a pointer, but this yields a GTK+ error.
In writing the handlers I assumed that it would operate like any library call. The input parameters would be on the return stack, supplied by GTK as the handler code executes, and I am supposed to put any returns into EAX. But this analysis could be wrong. I may be preparing the address wrong or handler"s parameters wrong, or have totally the wrong concept.
I am hoping that, despite the statement that handlers would have to be in C, there is some way to simulate what the C code would do, in assembler if necessary.
I sense that I am one hurdle away from making this breakthrough, and if anyone could send a few suggestions or places where I might look, I would be very grateful.
FUNCTION: g_signal_connect_data ( wptr name callback data 0 0 -- )
I see you're using things like ' CB.DELETE.EVENT +ORIGIN to pass as
the callback parameter.
Shouldn't you use a Forth callback to begin with? Your
CB.DELETE.EVENT (and the others) needs and expects a Forth
context.
In SwiftForth this can be achieved with
' CB.DELETE.EVENT 2 CB: *CB.DELETE>EVENT
Pass *CB.DELETE>EVENT as the callback parameter to g_signal_connect_data
CB: creates a wrapper around CB.DELETE.EVENT which establishes a
temporary Forth environment to run in. See the SwiftForth manual
for accessing the parameters given to callbacks. Of course the
other callbacks should be adapted likewise.
Note: SwiftForth deals with the inputs in a specific way. Other
Forth systems differ in how they handle the callback input
parameters. But in general it's good not to depend blindly on
the return stack. Always check the Forth documentation.
While the import-library words facilitate non-Forth functions to
run in a Forth environment, the reverse, running Forth words in
a foreign context, is done with the callback words. They allow
for signal handlers, completion handlers, exception handlers,
start routine for POSIX threads, method implementations for Objective-C
classes, etc., etc. Many Forth systems running under an OS like
SwiftForth, VFX, iForth, MacForth, iMops and Gforth provide ways
to create Forth callbacks. So any claim Forth can't be used here
is refuted I guess. See this Forth + GTK example.
BTW, I ran the adapted code in SwiftForth OS X. OK ;-)
I have tried the following code from myHDL manual on EDAPlayground.com, but it didn't print anything out for me. Can anyone show me why ? and how to solve this ?
My configuration on the site is outlined here.
Testbench+Design : Python only
Methodology : MyHDL 0.8
from random import randrange
from myhdl import *
ACTIVE_LOW, INACTIVE_HIGH = 0, 1
def Inc(count, enable, clock, reset, n):
""" Incrementer with enable.
count -- output
enable -- control input, increment when 1
clock -- clock input
reset -- asynchronous reset input
n -- counter max value
"""
#always_seq(clock.posedge, reset=reset)
def incLogic():
if enable:
count.next = (count + 1) % n
return incLogic
def testbench():
count, enable, clock = [Signal(intbv(0)) for i in range(3)]
# Configure your reset signal here (active type, async/sync)
reset = ResetSignal(0,active=ACTIVE_LOW,async=True)
## DUT to be instantiated
inc_1 = Inc(count, enable, clock, reset, n=4)
HALF_PERIOD = delay(10)
## forever loop : clock generator
#always(HALF_PERIOD)
def clockGen():
clock.next = not clock
## Stimulus generator
#instance
def stimulus():
reset.next = ACTIVE_LOW
yield clock.negedge
reset.next = INACTIVE_HIGH
for i in range(12):
enable.next = min(1, randrange(3))
yield clock.negedge
raise StopSimulation
#instance
def monitor():
print "enable count"
yield reset.posedge
while 1:
yield clock.posedge
yield delay(1)
print " %s %s" % (enable, count)
return clockGen, stimulus, inc_1, monitor
tb = testbench()
def main():
Simulation(tb).run()
You need to call the main() function at the end.
E.g., add a line
main()
at the end, or better, use Python's idiom of
if __name__=="__main__":
main()