How to use variables in Prolog query shell? - prolog

I know that I can use variables in Prolog shell (something like using '$' character, I think...but I don't remember...)
If I execute the following query it seems to work fine:
?- leggiFile('dataggare.txt', ListaTesto), tokenizzaLista(ListaTesto, TokenizedList, 1).
ListaTesto = [68, 117, 114, 97, 110, 116, 101, 32, 105|...],
TokenizedList = [t(1, [68, 117, 114, 97, 110, 116, 101]), t(-1, [32]), t(2, [105, 108]), t(-1, [32]), t(3, [77, 101, 100|...]), t(-1, [44]), t(-1, [32]), t(4, [...|...]), t(..., ...)|...]
But if I try to execute the two query leggiFile/2 and tokenizzaLista/2 separately, in this way go into error:
?- leggiFile('dataggare.txt', ListaTesto).
ListaTesto = [68, 117, 114, 97, 110, 116, 101, 32, 105|...].
?- tokenizzaLista($ListaTesto, TokenizedList, 1).
ERROR: variable `ListaTesto' does not exist
Why? it seems to me very strange. What am I missing?

?- open('uty.pl',read,S).
S = <stream>(0x236d4d0).
?- read($S,K).
K = (:-module(uty, [atoi//2, cache_file/2, cache_path/4, call_nth/2, cat/2, count_solutions/2, ... / ...|...])).
?- read($S,K).
K = (:-reexport(nb_uty, [ (<<)/2, (>>)/2, ++ / 2, (**)/2])).
...
but I'm not sure if garbage collection could disturb...
Documentation states
Bindings resulting from the successful execution of a top-level goal are asserted in a database if they are not too large.

Related

Ruby Newbie Needs to Convert a String to Byte Array with Some Padding

in Ruby I have a string like this:
myString = "mystring"
I want to convert the string to a byte array taking only the first 16 bytes and pad with 0's if shorter.
I can do this the brute force way. But...
Care to share a 'cool' way?
Something like this? You should probably check for edge cases like multibyte chars.
"my string"[0..15].ljust(16,'0')
You can get the string as a byte array by calling bytes on it, then once you have it as a byte array, you can take the first 16 elements. Finally, you pad the array by filling it with a range as the second argument:
def padded_byte_array(string, length = 16)
bytes = string.bytes.take(length)
bytes.fill(0, bytes.length...length)
end
and then you can call it:
padded_byte_array('my string')
# => [109, 121, 32, 115, 116, 114, 105, 110, 103, 0, 0, 0, 0, 0, 0, 0]
padded_byte_array('some super long string longer than 16 bytes')
# => [115, 111, 109, 101, 32, 115, 117, 112, 101, 114, 32, 108, 111, 110, 103, 32]
padded_byte_array('本当に長いマルチバイト文字列')
# => [230, 156, 172, 229, 189, 147, 227, 129, 171, 233, 149, 183, 227, 129, 132, 227]
I assume that if arr.size < str.size, where str is the string and arr is the array to be returned, str.bytes is returned. If, in that case, str.bytes[0, [str.size, arr.size].min] is to be returned, that requires an obvious adjustment.
def padded_bytes(str, arr_size)
str_bytes = str.bytes
Array.new([arr_size, str.size].max) { |i| str_bytes.fetch(i, 0) }
end
padded_bytes("tiger", 8)
#=> [116, 105, 103, 101, 114, 0, 0, 0]
padded_bytes("tiger", 3)
#=> [116, 105, 103, 101, 114]
Thanks folks for your answers.
In the end, I implemented
ba = name[0..15].ljust(16, "\0").bytes.to_a
Aza gave the closest to what I asked.
My original looked like this:
ba = name[0..15].bytes.to_a
while ba.length < 16 do ba.push(0) end
Until I got your answers. Thanks again!

How to assert list of values in ascending order?

Here is a list of values in an array:
[463, 246, 216, 194, 154, 152, 147, 140, 129, 128, 123, 118, 118, 102, 102, 101, 97, 96, 93, 85]
How can I ensure/assert through RSpec that the array list is in ascending order?
The simplest way is probably:
expect(array.sort).to eq(array)
"Ascending" means "the next element is not smaller than the current". You can encode that into a predicate easily:
expect(array.each_cons(2).all? {|a, b| a <= b }).to be_truthy
Note that Array#sort is not stable, so something like
expect(array.sort).to eq(array)
does not work!

Prolog: Reverse function of string_to_list

I know the Prolog-builtin "string_to_list". Now i need to reverse its functionality.
?- string_to_list('a*1+2', L).
L = [97, 42, 49, 43, 50].
How can i reverse this? Is there a builtin function?
Anything that does what "desiredfunction" does, would be a great help.
?- desiredfunction([97, 42, 49, 43, 50], R).
R = 'a*1+2'.
Thank you.
string_to_list/2 is deprecated in favor of string_codes/2.
The predicate is bidirectional, meaning that you can plug in a list, and get a string back on the other side.
string_codes(R, [97, 42, 49, 43, 50])
Better yet, use atom_codes/2, which is also bidirectional, and is more widely supported among Prolog implementations:
atom_codes(R, [97, 42, 49, 43, 50])
This produces
a*1+2

Unexpected output of a Prolog script

leftHand(empty).
rightHand(empty).
inHands :-
write("Left hand:"),
nl,
leftHand(X),
tab(2),
write(X),
nl,
nl,
write("Right hand:"),
rightHand(Y),
tab(2),
write(Y),
nl.
I expect inHands. to return something like this:
Left hand:
empty
Right hand:
empty
However, this is what I saw:
24 ?- inHands.
[76, 101, 102, 116, 32, 104, 97, 110, 100, 58]
empty
[82, 105, 103, 104, 116, 32, 104, 97, 110, 100, 58] empty
true.
What am I doing wrong here?
Turns out I have to use single quotes like this:
write('My text').

Two stars in a Prolog list

what are the two stars in a list?
[53, 5, 1, 53, 97, 115, 53, 50, 52, 121, 55, 56, 55, 97, 4, 1, 98, **]
I tried searching but no success.
The stars indicate that the term contains itself, e.g.
?- X = f(X).
X = f(**).
?- L = [53, L].
L = [53, **].
This is the case at least in older versions of SWI-Prolog.
See also https://lists.iai.uni-bonn.de/pipermail/swi-prolog/2009/001707.html.

Resources