Prolog Create Dictionaries - functional-programming

I understand that Prolog is not an object-oriented language, and after reading a few StackOverflow posts, it is not clear to me that this is feasible, but I figured I'd ask anyway:
If a Customer has and only has a name (atomic string) and an age (integer), is it possible to ask Prolog to give some examples of Customer dictionaries, given a list of possible names and an age range? Actual usage will feature extensive constraints on dictionary values.
For example, ideally I want something like this
between(18, 60, Customer.age),
member(Customer.name, [jodie, tengyu, adiche, tomoyo, wolfgang]),
Customer = whatisthis{age: What, name: Wot}.
to give me something like
Customer = whatisthis{age: 24, name: tomoyo} ;
Customer = whatisthis{age: 55, name: tengyu} ;
...
...

In SWI-Prolog, you actually do have dicts. Here:
?- between(2,3,X), Age is 20*X, member(Name, [tomoyo, tengyu]), Dict = customer{name:Name,
age:Age}.
X = 2,
Age = 40,
Name = tomoyo,
Dict = customer{age:40, name:tomoyo} ;
X = 2,
Age = 40,
Name = tengyu,
Dict = customer{age:40, name:tengyu} ;
X = 3,
Age = 60,
Name = tomoyo,
Dict = customer{age:60, name:tomoyo} ;
X = 3,
Age = 60,
Name = tengyu,
Dict = customer{age:60, name:tengyu}.
You can add and remove key-value pairs from dicts at run-time. The only limitation is that the keys must be atomic terms.
The documentation is here:
http://www.swi-prolog.org/pldoc/man?section=bidicts

Related

How to use the "6" char code in overloading insertion function on Scilab?

In the Help Documentation of Scilab 6.0.2, I can read the following instruction on the Overloading entry, regarding the last operation code "iext" showed in this entry's table:
"The 6 char code may be used for some complex insertion algorithm like x.b(2) = 33 where b field is not defined in the structure x. The insertion is automatically decomposed into temp = x.b; temp(2) = 33; x.b = temp. The 6 char code is used for the first step of this algorithm. The 6 overloading function is very similar to the e's one."
But I can't find a complete example on how to use this "char 6 code" to overload a function. I'm trying to use it, without success. Does anyone have an example on how to do this?
The code bellow creates a normal "mlist" as a example. Which needs overloading functions
A = rand(5,3)
names = ["colA" "colB" "colC"]
units = ["ft" "in" "lb"]
M = mlist(["Mlog" "names" "units" names],names,units,A(:,1),A(:,2),A(:,3))
Following are the overload functions:
//define display
function %Mlog_p(M)
n = size(M.names,"*")
formatStr = strcat(repmat("%10s ",1,n)) + "\n"
formatNum = strcat(repmat("%0.10f ",1,n)) + "\n"
mprintf(formatStr,M.names)
mprintf(formatStr,M.units)
disp([M(M.names(1)),M(M.names(2)),M(M.names(3))])
end
//define extraction operation
function [Mat]=%Mlog_e(varargin)
M = varargin($)
cols = [1:size(M.names,"*")] // This will also work
cols = cols(varargin($-1)) // when varargin($-1) = 1:1:$
Mat = []
if length(varargin)==3 then
for i = M.names(cols)
Mat = [Mat M(i)(varargin(1))]
end
else
for i=1:size(M.names(cols),"*")
Mat(i).name = M.names(cols(i))
Mat(i).unit = M.units(cols(i))
Mat(i).data = M(:,cols(i))
end
end
endfunction
//define insertion operations (a regular matrix into a Mlog matrix)
function ML=%s_i_Mlog(i,j,V,M)
names = M.names
units = M.units
A = M(:,:) // uses function above
A(i,j) = V
ML = mlist(["Mlog" "names" "units" names],names,units,A(:,1),A(:,2),A(:,3))
endfunction
//insertion operation with structures (the subject of the question)
function temp = %Mlog_6(j,M)
temp = M(j) // uses function %Mlog_e
endfunction
function M = %st_i_Mlog(j,st,M)
A = M(:,:) // uses function %Mlog_e
M.names(j) = st.name // uses function above
M.units(j) = st.unit // uses function above
A(:,j) = st.data // uses function above
names = M.names
units = M.units
M = mlist(["Mlog" "names" "units" names],names,units,A(:,1),A(:,2),A(:,3))
endfunction
The first overload (displays mlist) will show the matrix in the form of the following table:
--> M
M =
colA colB colC
ft in lb
0.4720517 0.6719395 0.5628382
0.0623731 0.1360619 0.5531093
0.0854401 0.2119744 0.0768984
0.0134564 0.4015942 0.5360758
0.3543002 0.4036219 0.0900212
The next overloads (extraction and insertion) Will allow the table to be access as a simple matrix M(i,j).
The extraction function Will also allow M to be access by column, which returns a structure, for instance:
--> M(2)
ans =
name: "colB"
unit: "in"
data: [5x1 constant]
The last two functions are the overloads mentioned in the question. They allow the column metadata to be changed in a structure form.
--> M(2).name = "length"
M =
colA length colC
ft in lb
0.4720517 0.6719395 0.5628382
0.0623731 0.1360619 0.5531093
0.0854401 0.2119744 0.0768984
0.0134564 0.4015942 0.5360758
0.3543002 0.4036219 0.0900212

Push dictionary? How to achieve this in Lua?

Say I have this dictionary in Lua
places = {dest1 = 10, dest2 = 20, dest3 = 30}
In my program I check if the dictionary has met my size limit in this case 3, how do I push the oldest key/value pair out of the dictionary and add a new one?
places["newdest"] = 50
--places should now look like this, dest3 pushed off and newdest added and dictionary has kept its size
places = {newdest = 50, dest1 = 10, dest2 = 20}
It's not too difficult to do this, if you really needed it, and it's easily reusable as well.
local function ld_next(t, i) -- This is an ordered iterator, oldest first.
if i <= #t then
return i + 1, t[i], t[t[i]]
end
end
local limited_dict = {__newindex = function(t,k,v)
if #t == t[0] then -- Pop the last entry.
t[table.remove(t, 1)] = nil
end
table.insert(t, k)
rawset(t, k, v)
end, __pairs = function(t)
return ld_next, t, 1
end}
local t = setmetatable({[0] = 3}, limited_dict)
t['dest1'] = 10
t['dest2'] = 20
t['dest3'] = 30
t['dest4'] = 50
for i, k, v in pairs(t) do print(k, v) end
dest2 20
dest3 30
dest4 50
The order is stored in the numeric indices, with the 0th index indicating the limit of unique keys that the table can have.
Given that dictionary keys do not save their entered position, I wrote something that should be able to help you accomplish what you want, regardless.
function push_old(t, k, v)
local z = fifo[1]
t[z] = nil
t[k] = v
table.insert(fifo, k)
table.remove(fifo, 1)
end
You would need to create the fifo table first, based on the order you entered the keys (for instance, fifo = {"dest3", "dest2", "dest1"}, based on your post, from first entered to last entered), then use:
push_old(places, "newdest", 50)
and the function will do the work. Happy holidays!

Length of nested array lua

I am having trouble figuring out how to get the length of a matrix within a matrix within a matrix (nested depth of 3). So what the code is doing in short is... looks to see if the publisher is already in the array, then it either adds a new column in the array with a new publisher and the corresponding system, or adds the new system to the existing array publisher
output[k][1] is the publisher array
output[k][2][l] is the system
where the first [] is the amount of different publishers
and the second [] is the amount of different systems within the same publisher
So how would I find out what the length of the third deep array is?
function reviewPubCount()
local output = {}
local k = 0
for i = 1, #keys do
if string.find(tostring(keys[i]), '_') then
key = Split(tostring(keys[i]), '_')
for j = 1, #reviewer_code do
if key[1] == reviewer_code[j] and key[1] ~= '' then
k = k + 1
output[k] = {}
-- output[k] = reviewer_code[j]
for l = 1, k do
if output[l][1] == reviewer_code[j] then
ltable = output[l][2]
temp = table.getn(ltable)
output[l][2][temp+1] = key[2]
else
output[k][1] = reviewer_code[j]
output[k][2][1] = key[2]
end
end
end
end
end
end
return output
end
The code has been fixed here for future reference: http://codepad.org/3di3BOD2#output
You should be able to replace table.getn(t) with #t (it's deprecated in Lua 5.1 and removed in Lua 5.2); instead of this:
ltable = output[l][2]
temp = table.getn(ltable)
output[l][2][temp+1] = key[2]
try this:
output[l][2][#output[l][2]+1] = key[2]
or this:
table.insert(output[l][2], key[2])

Encode a list of ids in an elegant id

I am trying to find the best way to encode a list of 10 integers (approximately between 1 and 10000) into a single id (I need a one-to-one function between a list of integers to a single integer or string).
I tried base64 (which is good because it is reversible), but the result is much longer than the input and that's quite bad.
For example, if I want to encode 12-54-235-1223-21-765-43-763-9522-908,
base64 gives me MTItNTQtMjM1LTEyMjMtMjEtNzY1LTQzLTc2My05NTIyLTkwOA==
Hashing functions are bad because I can't recover the input easily.
Maybe I could use the fact that I have only numbers as input and use number theory facts, someone has an idea?
If the integers are guaranteed to be smaller than 10^9, you could encode them as:
[number of digits in 1st number][1st number][number of digits in 2nd number][2nd number][...]
So 12,54,235,1223,21,765,43,763,9522,908 yields 21225432354122322137652433763495223908.
Sample Python implementation:
def numDigits(x):
if x < 10:
return 1
return 1 + numDigits(x/10)
def encode(nums):
ret = ""
for number in nums:
ret = ret + str(numDigits(number)) + str(number)
return ret
def decode(id):
nums = []
while id != "":
numDigits = int(id[0])
id = id[1:] #remove first char from id
number = int(id[:numDigits])
nums.append(number)
id = id[numDigits:] #remove first number from id
return nums
nums = [12,54,235,1223,21,765,43,763,9522,908]
id = encode(nums)
decodedNums = decode(id)
print id
print decodedNums
Result:
21225432354122322137652433763495223908
[12, 54, 235, 1223, 21, 765, 43, 763, 9522, 908]

Get value from array using any given t

What I am trying to accomplish, is to be able to put some values inside an array, then based on a t (0-1), get a value out of the array based on its stored values.
To make this more clear, here's an example:
Array values = [0, 10]
Now this array would return value 0 for t=1 and value 10 for t=1. So t=.3 will give a value of 3.
Another example:
Array values = [10, 5, 5, 35]
t=.25 will give a value of 5
t=.125 will give a value of 7.5
Im looking for the most efficient formula to get the value at any given t using a given array.
Currently I'm using this (pseudo code)
var t:Number = .25;
var values:Array = [10, 5, 5, 35];
if(t == 1) value = [values.length-1];
else
var offset:Number = 1/values.length;
var startIndex:int = int(t/offset);
var fraction:Number = t % offset;
var roundPart:Number = (values[startIndex+1] - values[startIndex]) * fraction;
var value:Number = values[startIndex] + roundPart;
But i'm sure there's a far more better way of doing this. So i'm calling for the mathematicians on here!
Here is a One Liner in Mathematica. It's doing the same thing you are, only slightly more compact.
Arrays indexes start at 1.
values = {10, 5, 5, 35, 0}
f[a_, x_] := a[[k = IntegerPart[(k1 = (Dimensions[a][[1]] - 2) x)] + 1]] +
FractionalPart[k1] (a[[k + 1]] - a[[k]])
So your interpolation result on:
In[198]:= f[values,1]
Out[198]= 35
Etc.
If you plot changing the x scale:

Resources