Im trying to write in a definition which takes a term and a set of tuples as argument but I don't know how to display the set of tuples
theory fullbb
imports
Main
begin
typedecl NAME
typedecl ADDRESS
locale addresbook
begin
definition address :: "NAME set ⇒ (NAME * ADDRESS) set ⇒ bool"
where
"address name addresses = (name = dom (addresses))"
end
The error message I get with this is
Type unification failed: Clash of types "_set" and "_=>_"
Type error in application: incompatible operand type
Operator: dom :: (??'a => ??'b option) => ??'a set
Operand: addresses :: (NAME x ADDRESS) set
The function dom returns the domain of a map, which is modeled in HOL as a function 'a => 'b option. For a relation (i.e., a set of tuples), the appropriate function is called Domain. So just use Domain instead of dom in your definition and it should type-check as expected.
The first step is to CNTL-click on pertinent functions to see what they do, and see what their type signature is.
For dom, it takes me to line 40 of Map.thy:
definition
dom :: "('a ~=> 'b) => 'a set" where
"dom m = {a. m a ~= None}"
It's looking like you're not dealing with tuples. There is this type synonym at line 13:
type_synonym ('a,'b) "map" = "'a => 'b option" (infixr "~=>" 0)
The locale is not important here. I change the tuple syntax to this:
definition address :: "NAME set => (NAME ~=> ADDRESS) set => bool"
where
"address name addresses = (name = dom (addresses))"
I still get a type error. It's because dom needs type (NAME ~=> ADDRESS).
definition address :: "NAME set => (NAME ~=> ADDRESS) => bool"
where
"address name addresses = (name = dom (addresses))"
So, dom is not what you thought it was.
Related
So I'm making a simple function in autolisp to count the number of a specific block in a drawing, and it looks like this:
(defun c:contarblocos()
(setq ss (ssget "x" ' ((0. "INSERT") (2. "Nome do bloco"))))
(setq count (sslength ss))
(alert(strcat "Total de blocos no desenho: " (itoa count)))
)
Now, what I really want is to count the number of blocks in a specific area, defined by the user. In other words, the user will call the function, and then the function will ask for a specific area, where it will look for the specific block and count them, not counting any blocks from outside the selected area.
Rather than using the x mode string of the ssget function (which searches the entire drawing database for all entities which fulfil the criteria of the filter list argument), simply omit this argument to permit the user to make a selection using any valid selection method, e.g.:
(defun c:contarblocos ( / sel )
(if (setq sel (ssget '((0 . "INSERT") (2 . "Nome do bloco"))))
(alert (strcat "Total de blocos no desenho: " (itoa (sslength sel))))
)
(princ)
)
There are a few other issues with your current code:
Always declare the variables whose scope is local to your function: in my above example, you will note that the sel symbol is declared in the variable list within the defun expression. For more information on why this is important, you may wish to refer to my tutorial here.
You should test whether ssget returns a valid selection set before calling the sslength function to obtain the number of items in the set, since (sslength nil) will error. You will see that I use an if statement in my code to accomplish this.
The ssget filter list argument should be an association list of dotted pairs, and as such, there should be a space between the key and the value in each list item, hence this:
(0. "INSERT")
Should become:
(0 . "INSERT")
You should include a final (princ) or (prin1) expression within the defun expression so that the function returns a null symbol to the command line, rather than returning the value returned by the last evaluated expression (i.e. the alert expression, which will return nil). Including a (princ) expression per my example will ensure that the function exits 'cleanly'.
I'm reading lambdasoup/soup.ml at master · aantron/lambdasoup · GitHub but I don't understand the syntax.
and 'a node =
{mutable self : 'b. 'b node option;
mutable parent : general node option;
values : [ `Element of element_values
| `Text of string
| `Document of document_values ]}
I don't understand 'b. 'b node option, if it was * it would be a tuple but it's the first time I see with . Also why the back-tic in the branches (e.g. `Element)?
The type 'a . type is a type that is explicitly polymorphic in 'a. So your example 'b . 'b node option is explcitly a field whose contents are polymorphic. In other words, any value assigned to the field must itself be polymorphic.
Here's an example with list rather than node:
type a = { mutable self : 'b. 'b list option; }
# let x = { self = None };;
val x : a = {self = None}
# x.self <- None;;
- : unit = ()
# x.self <- Some [];;
- : unit = ()
# x.self <- Some [3];;
Error: This field value has type int list option
which is less general than 'b. 'b list option
#
You can assign None to x.self because None is polymorphic (its type is 'a option, which works for any option type). You can assign Some [] to x.self because it's also polymorphic (its type is 'a list option, which works for any optional list). But you can't assign Some [3] to x.self because its type is int list option; in other words, it's not polymorphic.
You can find a discussion of explicitly polymorphic types in Section 5.2.1 of the OCaml manual.
Variant values with leading backquote like `A or `B are so-called polymorphic variants. This is a different feature than the usual variant types. The basic idea is that a polymorphic variant represents a value that is not necessarily part of any predefined type. The associated types are essentially sets of these values. Polymorphic variants can also be constructors as in your example type; that is, they can take an associated value. Just as you can have Some "yes", your definition allows one to have `Text "yes".
You can find some discussion of polymorphic variants in Section 7.4 of the OCaml manual (search for "polymorphic variant types").
I can't seem to get my code working enq. How am I supposed to declare the queue datattype as well?
let enq (q, x) =
match q with
queue ([], b) -> queue([], x::b)
| queue (f, []) -> queue(f, [x])
| queue (f, b) -> queue(f, x::b);;
You need to distinguish between the name of the type and the constructor names used to make elements of the type. For your code, the type name could be queue (type names begin with lower case) and you could have just a single constructor named Queue (constructors begin with upper case).
The type declaration would look like this then:
type 'a queue = Queue of 'a list * 'a list
Note that this type is parameterized by the type of the elements of the queue (denoted as 'a in the declaration).
In your code, the pattern matches should be against the constructor Queue, not against the type name queue.
I would also say as a side comment that all the cases in your code look the same to me. I suspect there might be just one case.
Why is it that given:
module type ENTRY = sig type t end
module type LOG = functor (E : ENTRY) -> sig type t end
This is a valid implementation of LOG
module Log :LOG = functor (LogEntry : ENTRY) ->
struct type t = LogEntry.t list end
But this isn't
module Log (LogEntry: ENTRY) :LOG = struct
type t = LogEntry.t list end
Error: Signature mismatch:
Modules do not match: sig type t = LogEntry.t list end is not included in LOG
If I remove the sig label (:LOG) from both definitions of Log then they return the same type as they are just syntactic sugar[1]
[1] http://caml.inria.fr/pub/docs/oreilly-book/html/book-ora132.html
The error message is confusing but the reason the first example passes and the second fails is actually very simple. Compare:
type entry = int
type log = int -> string
let log : log = fun s -> string_of_int s
and
let log (s : entry) : log = string_of_int s
The error message in case of modules states that a module field is not included in a functor, because an un-applied functor does not have fields.
ETA: a functor logically cannot have fields: functions/functors are a "different sort of beasts" than datastructures / modules. -- This makes the error message confusing, it sounds like we are asked to introduce a field although it already is present in the result of the functor.
Let me clarify on lukstafi's answer.
LOG is the type of the functor, in the first case it is matched against Log implementation itself (which happens to be a functor indeed), but in the second case it is matched against the result of the functor application (which happens to be an ordinary module), hence the mismatch.
All in all it looks like syntax misunderstanding. Read carefully the section on module types in the manual.
I've been looking at the if-let and when-let macros, Im having trouble determining what exactly it is that they "do". In particular, the documentation sais :
clojure.core/when-let
([bindings & body])
Macro
bindings => binding-form test
When test is true, evaluates body with binding-form bound to the value of test
I thus am somewhat confused about the way macros are documented.
1) What does the "=>" symbol mean ?
2) What does "test" refer to ?
Direct answer to your questions:
=> means "expands to", as in BNF notation. In this case it means that you need two forms: binding-form and the test.
"test" means anything that can be evaluated as bool.
By the way, I think that the docs are unclear or even maybe erroneous here. It is hard (or impossible) to deduce that the two forms constituting the bindings need to be enclosed in a vector. IMHO it should be either when-let ([[bindings] & body]) (the vector shown in the args) or bindings => [binding-form test] (the vector shown in the BNF-like expansion.)
It's often helpful when dealing with a macro to call macroexpand and see what the generated code is.
(macroexpand
'(if-let [x (myfunc)]
(foo x)
(bar))
; expands to
(let* [temp__3695__auto__ (myfunc)]
(if temp__3695__auto__ (clojure.core/let [x temp__3695__auto__]
(foo x))
(bar)))
; the generated symbols are necessary to avoid symbol
; capture but can confuse. The above is equivalent to:
(let* [ t (myfunc)]
(if t
(let [x t]
(foo x))
(bar))
So you can see that if-let is a shorthand for "bind local variable to the result of a function call and if that variable is truthy call the first form, else call the other form. The value returned by your function is only available in the 'truthy' branch."
wrt documentation convention
bindings => binding-form test
=> reads something like 'is equivalent to'
test is some form that returns a value
For most of these functions, clojuredocs is your friend, example usage often clarify things. If the clojuredocs example doesn't cut it for you, you can add your own
Consider the following code:
(if-let [x (a-function)]
(do-something-with x) ;; (a-function) returned a truthy result
(do-something-else) ;; (a-function) returned nil or false
This is like let, in that x will be bound to the return value of (a-function). This function could return nil or false. In that case, the implicit test fails and (do-something-else) will be evaluated. If x is not nil and not false, (do-something-with x) will be evaluated.
A scenario where this could be useful:
(if-let [user (find-logged-in-user)]
(do something with logged in user) ;; a user was found
(redirect to login page) ;; no user was found
I sometimes use something like the following, to conditionally add keys to a map of options:
(apply merge {:username "joe"
:email "joe#example.com"}
(when-let [name (find-full-name)] {:name name})
(when-let [dob (find-date-of-birth)] {:dob dob}))
This results in a map with :username and :email keys, and a :name key if the users' full name was found, plus a :dob key if a date of birth was found.
I hope that makes the use of if-let and when-let clearer.