Prolog program to divide words into syllables using predicate - append

ndProlog program should divide words into syllables using predicate:
1. syllable:vowel consonant vowel, 2. syllable: vowel consonant consonant vowel.
For example; Bum-per
My program can not do it
vowel(a).
vowel(e).
vowel(i).
vowel(o).
vowel(u).
vowel(y).
consonant(L) :- not(vowel(L)).
append([X|Y],Z,[X|W]) :- append(Y,Z,W).
append([],X,X).
append([X,X1,X2,'-'],
sylsplit(_,[]).
sylsplit([X,X1,X2|Y],[X,X1,X2,'-'|W]) :- vowel(X1), consonant(X2), vowel(X3), sylsplit(Y,W).
sylsplit([X|Y],[X|W]) :- sylsplit(Y,W).
sylsplit([],L).
%sylsplit([a,n,a,l,o,g],L).

Going through sylsplit in order:
You first rule says ANTYHING has a split of empty-list; pretty sure that's not right, as your result shouldn't be SHORTER than your input.
Your second rule checks that X3 is a vowel, but never matches X3 against anything; similarly, it doesn't check X for anything.
Your third rule looks OK.
Your last rule says that an empty list should have a result of... an undefined variable?
Also I can't believe that not is predefined but append isn't (and your 3rd line of append is incomplete).

Related

Can I write a PCRE conditional that only needs the no-match part?

I am trying to create a regular expression to determine if a string contains a number for an SQL statement. If the value is numeric, then I want to add 1 to it. If the number is not numeric, I want to return a 1. More or less. Here is the SQL:
SELECT
field,
CASE
WHEN regexp_like(field, '^ *\d*\.?\d* *$') THEN dec(field) + 1
ELSE 1
END nextnumber
FROM mytable
This actually works, and returns something like this:
INVALID 1
00000 1
00001E 1
00379 380
00013 14
99904 99905
But to push the envelope of understanding, what if I wanted to cover negative numbers, or those with a positive sign. The sign would have to immediately precede or follow the number, but not both, and I would not want to allow white space between the sign and the number.
I came up with a conditional expression with a capture group to capture the sign on the front of the number to determine if a sign was allowed on the end, but it seems a little awkward to handle given I don't really need a yes-pattern.
Here is the modified regex: ^ ([+-]?)*\d*\.?\d*(?(1) *|[+-]? *)$
This works at regex101.com, but in order for it to work I need to have something before the pipe, so I have to duplicate the next pattern in both the yes-pattern and the no-pattern.
All that background for this question: How can I avoid that duplication?
EDIT: DB2 for i uses International Components for Unicode to provide regular expression processing. It turns out that this library does not support conditionals like PRCE, so I changed the tags on this question. The answer given by Wiktor Stribiżew provides a working alternative to the conditional by using a negative lookahead.
You do not have to duplicate the end pattern, just move it outside the conditional:
^ *([+-])?\d*\.?\d*(?(1)|[+-]?) *$
See the regex demo. So, the yes-part is empty, and the no-part has an optional pattern.
You may also solve it with a mere negative lookahead:
^ *([+-](?!.*[-+]))?\d*\.?\d*[+-]? *$
See another regex demo. Here, ([+-](?!.*[-+]))? matches (optionally) a + or - that are not followed with any 0+ char followed with another + or -.

How does the following quine work?

According to wikipedia :
A quine is a non-empty computer program which takes no input and produces a copy of its own source code as its only output
I saw this piece of perl code and am not able to figure out how it works.
Save the following line in file /tmp/p and run the file as perl /tmp/p:
Illegal division by zero at /tmp/p line 1.
The output of perl /tmp/p is:
Illegal division by zero at /tmp/p line 1.
How is the code working?
First, try to run it with warnings turned on:
$ perl -w p
Unquoted string "at" may clash with future reserved word at p line 1.
Unquoted string "tmp" may clash with future reserved word at p line 1.
Argument "tmp" isn't numeric in division (/) at p line 1.
Argument "at" isn't numeric in division (/) at p line 1.
The first two warnings are from the compile phase.
Let's look at the Deparse output:
$ perl -MO=Deparse p
'division'->Illegal('zero'->by('at' / 'tmp' / 'line'->p(1)));
p syntax OK
In essence, the value of at divided by tmp divided by the return value of another method invocationp is passed as an argument to the method by invoked on the class 'zero'. at and tmp are considered to be strings, and their numeric values are zero. Therefore, at/tmp results in the illegal division by zero error.
You will get the same error if you change the file's contents to
Stackoverflow hacker news one at /tmp/p line 1.
If you are wondering how Illegal division becomes 'division'->Illegal, see indirect object syntax, and avoid using it.
I would prefer to see you concentrating on improving the quality of your Perl code, rather than investigating obscure corners
But the answer is that the line is parsed as
'division'->Illegal('zero'->by('at' / 'tmp' / 'line'->p(1)));
and Perl uses zero for 'at' and 'tmp' because they are not valid numeric strings, so the first action is to evaluate 0 / 0 which throws the error

how can i do that pattern ?(pattern with asterisks only)

Qu.17 Write down the program to output the pattern given below using appropriate control structures. Use of control structures is compulsory in this program.
(*****)
(****)
(***)
(**)
(*)
(**)
(***)
(****)
(*****)
edit: have removed probable extra (**)
sounds like a college assignment to me :)
break down the problem into its simplest form and write a test to check your program.
your first test could be something really simple:
can print out single asterisk: (*)
then build it up from there:
given starting number of 2, prints 3 lines of two asterisks (**), (**), (**)
second line should only have one asterisk (**), (*), (**)
...
given starting number x, prints 2x - 1 lines

Checking the format of a string in Matlab

So I'm reading multiple text files in Matlab that have, in their first columns, a column of "times". These times are either in the format 'MM:SS.milliseconds' (sorry if that's not the proper way to express it) where for example the string '29:59.9' would be (29*60)+(59)+(.9) = 1799.9 seconds, or in the format of straight seconds.milliseconds, where '29.9' would mean 29.9 seconds. The format is the same for a single file, but varies across different files. Since I would like the times to be in the second format, I would like to check if the format of the strings match the first format. If it doesn't match, then convert it, otherwise, continue. The code below is my code to convert, so my question is how do I approach checking the format of the string? In otherwords, I need some condition for an if statement to check if the format is wrong.
%% Modify the textdata to convert time to seconds
timearray = textdata(2:end, 1);
if (timearray(1, 1) %{has format 'MM.SS.millisecond}%)
datev = datevec(timearray);
newtime = (datev(:, 5)*60) + (datev(:, 6));
elseif(timearray(1, 1) %{has format 'SS.millisecond}%)
newtime = timearray;
You can use regular expressions to help you out. Regular expressions are methods of specifying how to search for particular patterns in strings. As such, you want to find if a string follows the formats of either:
xx:xx.x
or:
xx.x
The regular expression syntax for each of these is defined as the following:
^[0-9]+:[0-9]+\.[0-9]+
^[0-9]+\.[0-9]+
Let's step through how each of these work.
For the first one, the ^[0-9]+ means that the string should start with any number (^[0-9]) and the + means that there should be at least one number. As such, 1, 2, ... 10, ... 20, ... etc. is valid syntax for this beginning. After the number should be separated by a :, followed by another sequence of numbers of at least one or more. After, there is a . that separates them, then this is followed by another sequence of numbers. Notice how I used \. to specify the . character. Using . by itself means that the character is a wildcard. This is obviously not what you want, so if you want to specify the actual . character, you need to prepend a \ to the ..
For the second one, it's almost the same as the first one. However, there is no : delimiter, and we only have the . to work with.
To invoke regular expressions, use the regexp command in MATLAB. It is done using:
ind = regexp(str, expression);
str represents the string you want to check, and expression is a regular expression that we talked about above. You need to make sure you encapsulate your expression using single quotes. The regular expression is taken in as a string. ind would this return the starting index of your string of where the match was found. As such, when we search for a particular format, ind should either be 1 indicating that we found this search at the beginning of the string, or it returns empty ([]) if it didn't find a match. Here's a reproducible example for you:
B = {'29:59.9', '29.9', '45:56.8', '24.5'};
for k = 1 : numel(B)
if (regexp(B{k}, '^[0-9]+:[0-9]+\.[0-9]+') == 1)
disp('I''m the first case!');
elseif (regexp(B{k}, '^[0-9]+\.[0-9]+') == 1)
disp('I''m the second case!');
end
end
As such, the code should print out I'm the first case! if it follows the format of the first case, and it should print I'm the second case! if it follows the format of the second case. As such, by running this code, we get:
I'm the first case!
I'm the second case!
I'm the first case!
I'm the second case!
Without knowing how your strings are formatted, I can't do the rest of it for you, but this should be a good start for you.

matlab regexprep

How to use matlab regexprep , for multiple expression and replacements?
file='http:xxx/sys/tags/Rel/total';
I want to replace 'sys' with sys1 and 'total' with 'total1'. For a single expression a replacement it works like this:
strrep(file,'sys', 'sys1')
and want to have like
strrep(file,'sys','sys1','total','total1') .
I know this doesn't work for strrep
Why not just issue the command twice?
file = 'http:xxx/sys/tags/Rel/total';
file = strrep(file,'sys','sys1')
strrep(file,'total','total1')
To solve it you need substitute functionality with regex, try to find in matlab's regexes something similar to this in php:
$string = 'http:xxx/sys/tags/Rel/total';
preg_replace('/http:(.*?)\//', 'http:${1}1/', $string);
${1} means 1st match group, that is what in parenthesis, (.*?).
http:(.*?)\/ - match pattern
http:${1}1/ - replace pattern with second 1 as you wish to add (first 1 is a group number)
http:xxx/sys/tags/Rel/total - input string
The secret is that whatever is matched by (.*?) (whether xxx or yyyy or 1234) will be inserted instead of ${1} in replace pattern, and then replace instead of old stuff into the input string. Welcome to see more examples on substitute functionality in php.
As documented in the help page for regexprep, you can specify pairs of patterns and replacements like this:
file='http:xxx/sys/tags/Rel/total';
regexprep(file, {'sys' 'total'}, {'sys1' 'total1'})
ans =
http:xxx/sys1/tags/Rel/total1
It is even possible to use tokens, should you be able to define a match pattern for everything you want to replace:
regexprep(file, '/([st][yo][^/$]*)', '/$11')
ans =
http:xxx/sys1/tags/Rel/total1
However, care must be taken with the first approach under certain circumstances, because MATLAB replaces the pairs one after another. That is to say if, say, the first pattern matches a string and replaces it with something that is subsequently matched by a later pattern, then that will also be replaced by the later replacement, even though it might not have matched the later pattern in the original string.
Example:
regexprep('This\is{not}LaTeX.', {'\\' '([{}])'}, {'\\textbackslash{}' '\\$1'})
ans =
This\textbackslash\{\}is\{not\}LaTeX.
=> This\{}is{not}LaTeX.
and
regexprep('This\is{not}LaTeX.', {'([{}])' '\\'}, {'\\$1' '\\textbackslash{}'})
ans =
This\textbackslash{}is\textbackslash{}{not\textbackslash{}}LaTeX.
=> This\is\not\LaTeX.
Both results are unintended, and there seems to be no way around this with consecutive replacements instead of simultaneous ones.