I have a question about Mathematica's SimilarityRules defining (for e.g. SequenceAlignment function). So help centre clearly stands for
"SimilarityRules -> {{a_, a_} -> 1, {a_, b_} -> -1}, giving a score of +1 for any pair of identical elements, and a score of -1 for any mismatch, deletion or insertion."
Ok, I get it, but what if I want to give different score for mismatch, and different for indeles? I tried:
SimilarityRules -> {{a_, a_} -> 3, {{a_, b_} && {{a_!=""} && {b_ != ""}}} -> -8} and many other combination of {}, && positions, but it doesn't seem to help. Any suggestions, is it just a typo I'm doing, or it's rather a silly idea to define it like this?
Edit.. sorry about answering too quickly: SequenceAlignment does not seem to work with such conditionals.. I'd sugest you ask over on mathematica.stackexchange.com. I'd also sugest you provide an example of input and expected output to clarify what you are trying to acomplish.
your question really is about pattern testing .. here are two ways to do what you want with patterns..
{{"A", "A"}, {"A", "B"}, {"A", ""}} /. {
{a_, b_} /; a == b -> 1,
{a_, b_} /; (a != b && b != "" && a != "") -> -8,
{a_, b_} /; (a != b ) -> -1
}
{{"A", "A"}, {"A", "B"}, {"A", ""}} /. {
{_, _}?((#[[1]] == #[[2]]) &) -> 1,
{_, _ }?((#[[1]] != #[[2]] && #[[1]] != "" && #[[2]] != "") &) -> -8,
{_, _}?((#[[1]] != #[[2]]) &) -> -1
}
These are doing the same thing and produce {1,-8,-1} basically with slightly differenct syntax, see Pattern Test and Condition in the manual.
Related
function method ListMap<T,X>(f : (T -> X), l : List<T>) : List<X>
ensures ListMap(x => x + 1, Cons(1, Cons(2, Nil))) == Cons(2, Cons(3, Nil))
{
match l {
case Nil => Nil
case Cons(n, l') => Cons(f(n), ListMap(f, l'))
}
}
Dafny raises two complaint here.
about "case Nil": A postcondition might not hold on this return path.
about "ensure...": This postcondition might not hold on a return path.
This snippet is from the book "Introducing Software Verification with Dafny Language: Proving Program Correctness", but I can't find the Errata for it.
There are two things here that you can solve at once:
The ensures won't terminate if computed (in an imaginary ghost environment) because you provide it as an intrinsic postcondition, so you will get into trouble.
Dafny is ok to ensure something about the output of the current function, but for everything other call to the function itself, it has to prove termination.
What you provide is an example of a postcondition, not a fact that ought to be known by every user of your ListMap function.
The solution is to refactor your ensures in a lemma:
datatype List<T> = Nil | Cons(t: T, tail: List<T>)
function method ListMap<T,X>(f : (T -> X), l : List<T>) : List<X>
{
match l {
case Nil => Nil
case Cons(n, l') => Cons(f(n), ListMap(f, l'))
}
}
lemma ListMapExample()
ensures ListMap(x => x + 1, Cons(1, Cons(2, Nil))) == Cons(2, Cons(3, Nil))
{
}
I have no idea what is the problem,
this is the code-
solve_bdd(BddTree, ListVars) ->
findRes(BddTree, maps:from_list(ListVars++[{one, 1}, {zero, 0}])).
findRes(BddTree, Map) when is_record(BddTree, node)-> Val = maps:get(getName(BddTree)), Name = getName(BddTree),
if Name=='one' or Name=='zero' -> maps:get(getName(BddTree));
(Val==1 or Val=='true') -> findRes(getRight(BddTree), Map);
(Val==0 or Val=='false') -> findRes(getLeft(BddTree), Map);
true -> error
end;
findRes(_, _) -> error.
And the shell errors-
exf.erl:183: syntax error before: '=='
exf.erl:180: function findRes/2 undefined
exf.erl:21: Warning: function getRight/1 is unused
exf.erl:22: Warning: function getLeft/1 is unused
error
When there is multiple conditions, You should group operands of or operator in parentheses:
1> false or false.
false
2> false == true or false == true.
* 1: syntax error before: '=='
2> (false == true) or (false == true).
false
Also maps:get/1 (function get in module maps which accepts 1 parameter) that you used:
maps:get( getName(BddTree) )
does not exists! But you can use maps:get/2 or maps:get/3.
Most of the time you can use case expression instead of if expression.
Also sometimes it's better to use orlese operator instead of or.
It's better to not handle anything! instead of handling both 0 and 1 and boolean types, you can use one of them and remove unnecessary checks.
By convention in Erlang it's better to write function and record names in Snake_case.
BTW, your findRes/2 function would be like:
%%% I don't know what work you expect from this function so if it's not working
%%% just like your own, try to fix it!
% findRes -> find_res
find_res(BddTree, Map) when is_record(BddTree, node) ->
% Sounds like BddTree is a record. If by `get_name/1` you just want to
% access one of it's elements, you can simply write BddTree#node.<ELEMENT_NAME>
% getName -> get_name
case get_name(BddTree) of
% you don't have to use ' character for atoms:
Name when Name == one orelse Name == zero ->
% I thinkd you've missed `Map`:
maps:get(get_name(BddTree), Map);
_ ->
% I do not use 0 and 1 and just use boolean type:
find_res(
% I thinkd you've missed `Map`:
case maps:get(get_name(BddTree), Map) of
Val when Val -> % when Val == true
% getRight -> get_right
get_right(BddTree);
_ -> % Assume false
get_left(BddTree)
end,
Map
)
end;
find_res(_, _) -> error.
And let's look at above code without comments:
find_res(BddTree, Map) when is_record(BddTree, node) ->
case get_name(BddTree) of
Name when Name == one orelse Name == zero ->
maps:get(get_name(BddTree), Map);
_ ->
find_res(
case maps:get(get_name(BddTree), Map) of
Val when Val -> % when Val == true
get_right(BddTree);
_ ->
get_left(BddTree)
end,
Map
)
end;
find_res(_, _) -> error.
I work with erlang
I want to make a function that will check if the Cin and Id is not null
I tried with:
if Cin /= null && Id/=null -> {ok,Cin et Id sont différents de null};
true -> {nok,Cin et Id sont null}
end.
I know that the notion of '&&' does not exist in erlang
but I can not find the equivalent of this notion in erlang
In Erlang, use andalso instead of &&:
if Cin /= null andalso Id/=null -> {ok,Cin et Id sont différents de null};
The use of andalso is short-circuiting and is equivalent to &&. The regular and operator always evaluates both sides of the expression and is not short-circuiting.
Usually, it is better to use a match:
case {Cin, Id} of
{null, _} -> cin_null;
{_, null} -> id_null;
{_, _} -> not_null
end
But also note that you can get away with not checking at all. Add a guard in the function head:
my_func(Cin, Id) when is_integer(Cin), is_binary(Id) ->
do_something.
If this fails to match, you have a crash, but this is usually what you expect to happen in the code base.
You can create function and use pattern matching:
is_null(null, null) ->
true;
is_null(_, _) ->
false.
in console:
1> c(some_mod).
{ok,some_mod}
2> some_mod:is_null(null, 1).
false
3> some_mod:is_null(1, 1).
false
4> some_mod:is_null(null, null).
true
I'm trying to write some Erlang that would filter an array in the form:
[{dakota, "cold and snowy"}, {california, "perfect weather"}] % and so on
Here is what I've got - I get a syntax error when I try to make a .beam from werl.
-module(matcher).
-export([findkeywords/2]).
findkeywords(Word, Arr) ->
IsMatch = fun({Key, Desc}) ->
lists:any(fun(X) -> X==Word end, string:tokens(Desc, " ")),
lists:filter(IsMatch, [{K, V} || {K, V} <- Arr]).
Can anyone spot where my syntax is off?
I saw your call to arms on twitter and just had to come take a look. :D
If you want this to compile, you're just missing an end on your fun on line 6. Add it in and it compiles without complaint.
-module(matcher).
-export([findkeywords/2]).
findkeywords(Word, Arr) ->
IsMatch = fun({Key, Desc}) ->
lists:any(fun(X) -> X==Word end, string:tokens(Desc, " ")) end, % ADD THE END HERE
lists:filter(IsMatch, [{K, V} || {K, V} <- Arr]).
You can clean this up a bit too, unless this is an exercise in string matching for yourself. The string module has str(String, SubString) -> Index and rstr(String, SubString) -> Index that are described as such in the Erlang Manual:
Returns the position where the first/last occurrence of SubString begins in String. 0 is returned if SubString does not exist in String. For example:
> string:str(" Hello Hello World World ", "Hello World").
8
Using this tidies it up a bit, and you could even shorten the whole thing into a one liner. The list comprehension is unnecessary as the data is already in the format that you're trying to feed it in.
-module(matcher).
-export([findkeywords/2]).
findkeywords(Word, Arr) ->
lists:filter(fun({_Key, Desc}) -> string:str(Desc, Word) > 0 end, Arr).
You miss one "end" from the two functions. Also, it looks like the list comprehension in this example used is not needed.
findkeywords(Word, Arr) ->
IsMatch =
fun({_, Desc}) -> lists:any(fun(X) -> X == Word end, string:tokens(Desc, " ")) end,
lists:filter(IsMatch, [{K, V} || {K, V} <- Arr]).
You are missing the end key word for one of the funs. However, looks like you are searching within strings. This is normally what is use
-define(DATA,[{dakota, "cold and snowy"}, {california, "perfect weather"}]).
string_contains(Big,Small)-> string:rstr(Big,Small) > 0.
findkeywords(Word)-> [X || X <- ?DATA,string_contains(element(2,X),Word) == true].
Anyway, one of your funs was not ended well. that's all.
In an effort to understand the capabilities of functional programming I put together a few basic functions that you can compose together to build complex regular expressions. Now after some testing I have found this works but you can write some horrible code in any language that will work. Is this the kind of code you would find a professional F# programmer writing or am I abusing the feature?
Note: test is specifically what I am referring to.
type State = { input:string; index:int; succeeded:bool }
type Matcher = State -> State
let term (cs:char Set) =
fun s ->
if s.succeeded && s.index < s.input.Length && cs.Contains s.input.[s.index] then
{ input = s.input; index = s.index + 1; succeeded = true }
else
{ input = s.input; index = s.index; succeeded = false }
let quantify (term, min, max) =
let rec inner (s:State, count) =
if s.succeeded && s.index < s.input.Length && count <= max then
inner (term { input = s.input; index = s.index + 1; succeeded = true }, count + 1)
elif count >= min && count <= max then
{ input = s.input; index = s.index - 1; succeeded = true }
else
s
fun s -> inner (s, 0)
let disjunction leftTerm rightTerm =
fun s ->
let left = leftTerm s
if not left.succeeded then
let right = rightTerm s
if not right.succeeded then
{ input = s.input; index = s.index; succeeded = false }
else
right
else
left
let matcher input terms =
let r = terms { input = input; index = 0; succeeded = true }
if r.succeeded then r.input.Substring (0, r.index) else null
let test = // (abc|xyz)a{2,3}bc
disjunction // (abc|xyz)
(term (set "a") >> term (set "b") >> term (set "c"))
(term (set "x") >> term (set "y") >> term (set "z"))
>> quantify (term (set "a"), 2, 3) // (a{2,3})
>> term (set "b") // b
>> term (set "c") // c
let main () : unit =
printfn "%s" (matcher "xyzaabc" test)
System.Console.ReadKey true |> ignore
main()
The code looks pretty good to me.
I'm not sure if this was your intention or a coincidence, but you're implementing something quite similar to "parser combinators", which is a topic of many academic papers :-). I think that Monadic Parser Combinators is quite readable (it has examples in Haskell, but you should be able to translate them to F#).
Regarding the function composition operator. I'm generally not a big fan of using the operator too much, because it often obfuscates the code. However, in your example it makes a good sense because you can easily imagine that >> means "this group should be followed by that group", which is easy to interpret.
The only minor change that I would do is to choose some nice custom operator for the disjunction operation and define a few more primitive operations, so that you can write for example this:
// Test against several terms in sequence
let sequence terms = (fun state -> terms |> Seq.fold (>>) state)
// Test for a substring
let substring s = sequence [ for c in s -> term (set [c]) ]
let test = // (abc|xyz)a{2,3}bc
( substring "abc" <|> substring "xyz" )
>> quantify 2 3 (term (set "a")) // (a{2,3})
>> substring "bc" // bc
This is more higher-level description, so it removes some of the >> operators in favor of functions that are more descriptive (and encapsulate >>). I also changed quantify to take multiple arguments instead of a tripple (which is a minor change)
If you want to play with this further, then you can take a look at the article and try to write F# computation expression builder that would allow you to use parser { .. } syntax.
This is generally good style but you're missing some tricks and still have quite a bit of redundancy. Maybe more like this:
let valid (s: State) = s.succeeded && s.index < s.input.Length
...
let disjunction leftTerm rightTerm s =
let left = leftTerm s
if left.succeeded then left else
let right = rightTerm s
if right.succeeded then right else
{ s with succeeded = false }
...
let test =
let f s = set s |> term
let (++) s t = f s >> f t
disjunction ("a" ++ "b" ++ "c") ("x" ++ "y" ++ "z")
>> quantify (f "a", 2, 3)
>> "b" ++ "c"
You might prefer to accumulate a value representing a computation rather than closures because it makes debugging much easier.