| Methods_for_Nongenerics {methods} | R Documentation |
In writing methods for an R package, it's common for these methods to
apply to a function (in another package) that is not generic in that
package; that is, there are no formal methods for the function in its
own package, although it may have S3 methods.
The programming in this case involves one extra step, to call
setGeneric()
to declare that the function is
generic in your package.
Calls to the function in your package will then use all methods defined there or in any other loaded package that creates the same generic function. Similarly, calls to the function in those packages will use your methods.
The original version, however, remains non-generic. Calls in that package or in other packages that use that version will not dispatch your methods except for special circumstances:
If the function is one of the primitive functions that accept methods, the internal C implementation will dispatch methods if one of the arguments is an S4 object, as should be the case.
If the other version of the function dispatches S3 methods and your methods are also registered as S3 methods, the method will usually be dispatched as that S3 method.
Otherwise, you will need to ensure that all calls to the function come from a package in which the function is generic, perhaps by copying code to your package.
Details and the underlying reasons are discussed in the following sections.
Creating methods for a function (any function) in a package means that calls to the function in that package will select methods according to the actual arguments. However, if the function was originally a non-generic in another package, calls to the function from that package will not dispatch methods. In addition, calls from any third package that imports the non-generic version will also not dispatch methods. This section considers the reason and how one might deal with the consequences.
The reason is simply the R namespace mechanism and its role in evaluating function calls. When a name (such as the name of a function) needs to be evaluated in a call to a function from some package, the evaluator looks first in the frame of the call, then in the namespace of the package and then in the imports to that package.
Defining methods for a function in a package ensures that calls to the function in that package will select the methods, because a generic version of the function is created in the namespace. Similarly, calls from another package that has or imports the generic version will select methods. Because the generic versions are identical, all methods will be available in all these packages.
However, calls from any package that imports the old version or just selects it from the search list will usually not select methods.
A an example, consider the function
data.frame()
in the base package.
This function takes any number of objects as arguments and attempts to combine
them as variables into a data frame object.
It does this by calling as.data.frame()
, also in the
base package, for each of the objects.
A reasonable goal would be to extend the classes of objects that can
be included in a data frame by defining methods for
as.data.frame()
.
But calls to data.frame()
,
will still use the version of that function in the base package, which
continues to call the non-generic as.data.frame()
in
that package.
The details of what happens and options for dealing with it depend on the form of the function: a primitive function; a function that dispatches S3 methods; or an ordinary R function.
Primitive functions are not actual R function objects. They go directly to internal C code. Some of them, however, have been implemented to recognize methods. These functions dispatch both S4 and S3 methods from the internal C code. There is no explicit generic function, either S3 or S4. The internal code looks for S4 methods if the first argument, or either of the arguments in the case of a binary operator, is an S4 object. If no S4 method is found, a search is made for an S3 method. So defining methods for these functions works as long as the relevant classes have been defined, which should always be the case.
A function dispatches S3 methods by calling
UseMethod()
, which does not look for
formal methods regardless of whether the first argument is an S4
object or not.
This applies to the as.data.frame()
example above.
To have methods called in this situation, your package must also define the
method as an S3 method, if possible. See section ‘S3
“Generic” Functions’.
In the third possibility, the function is defined with no expectation
of methods.
For example, the base package has a number of functions that compute
numerical decompositions of matrix arguments.
Some, such as chol()
and qr()
are implemented to dispatch S3 methods; others, such as
svd()
are implemented directly as a specific
computation.
A generic version of the latter functions can be written and called
directly to define formal methods, but no code in another package that
does not import this generic version will dispatch such methods.
In this case, you need to have the generic version used in all the indirect calls to the
function supplying arguments that should dispatch methods.
This may require supplying new functions that dispatch methods and
then call the function they replace.
For example, if S3 methods did not work for
as.data.frame()
, one could call a function that
applied the generic version to all its arguments and then called
data.frame()
as a replacement for that function.
If all else fails, it might be necessary to copy over the relevant
functions so that they would find the generic versions.
S3 method dispatch looks at the class of the first
argument.
S3 methods are ordinary functions with the same arguments as the
generic function.
The “signature” of an S3 method is identified by the name to
which the method is assigned, composed of the name of the
generic function, followed by "."
, followed by the name of the class.
For details, see UseMethod
.
To implement a method for one of these functions corresponding to S4
classes, there are two possibilities: either an S4 method or an S3 method with the
S4 class name.
The S3 method is only possible if the intended signature has the
first argument and nothing else.
In this case,
the recommended approach is to define the S3 method and also supply the
identical function as the definition of the S4 method.
If the S3 generic function was f3(x, ...)
and the S4 class for
the new method was
"myClass"
:
f3.myClass <- function(x, ...) { ..... }
setMethod("f3", "myClass", f3.myClass)
Defining both methods usually ensures that all calls to the original function will dispatch the intended method. The S4 method alone would not be called from other packages using the original version of the function. On the other hand, an S3 method alone will not be called if there is any eligible non-default S4 method.
S4 and S3 method selection are designed to follow compatible rules of
inheritance, as far as possible.
S3 classes can be used for any S4 method selection, provided that the
S3 classes have been registered by a call to
setOldClass
, with that call specifying the correct S3
inheritance pattern.
S4 classes can be used for any S3 method selection; when an S4 object
is detected, S3 method selection uses the contents of
extends(class(x))
as the equivalent of the S3
inheritance (the inheritance is cached after the first call).
An existing S3 method may not behave as desired for an S4 subclass, in
which case utilities such as asS3
and
S3Part
may be useful. If the S3 method fails on the S4
object, asS3(x)
may be passed instead; if the object returned
by the S3 method needs to be incorporated in the S4 object, the
replacement function for S3Part
may be useful.
Chambers, John M. (2016) Extending R, Chapman & Hall. (Chapters 9 and 10.)
Methods_for_S3 for suggested implementation of methods that work for both S3 and S4 dispatch.
## A class that extends a registered S3 class inherits that class' S3 ## methods. setClass("myFrame", contains = "data.frame", slots = c(timestamps = "POSIXt")) df1 <- data.frame(x = 1:10, y = rnorm(10), z = sample(letters,10)) mydf1 <- new("myFrame", df1, timestamps = Sys.time()) ## "myFrame" objects inherit "data.frame" S3 methods; e.g., for `[` mydf1[1:2, ] # a data frame object (with extra attributes) ## a method explicitly for "myFrame" class setMethod("[", signature(x = "myFrame"), function (x, i, j, ..., drop = TRUE) { S3Part(x) <- callNextMethod() x@timestamps <- c(Sys.time(), as.POSIXct(x@timestamps)) x } ) mydf1[1:2, ] setClass("myDateTime", contains = "POSIXt") now <- Sys.time() # class(now) is c("POSIXct", "POSIXt") nowLt <- as.POSIXlt(now)# class(nowLt) is c("POSIXlt", "POSIXt") mCt <- new("myDateTime", now) mLt <- new("myDateTime", nowLt) ## S3 methods for an S4 object will be selected using S4 inheritance ## Objects mCt and mLt have different S3Class() values, but this is ## not used. f3 <- function(x)UseMethod("f3") # an S3 generic to illustrate inheritance f3.POSIXct <- function(x) "The POSIXct result" f3.POSIXlt <- function(x) "The POSIXlt result" f3.POSIXt <- function(x) "The POSIXt result" stopifnot(identical(f3(mCt), f3.POSIXt(mCt))) stopifnot(identical(f3(mLt), f3.POSIXt(mLt))) ## An S4 object selects S3 methods according to its S4 "inheritance" setClass("classA", contains = "numeric", slots = c(realData = "numeric")) Math.classA <- function(x) { (getFunction(.Generic))(x@realData) } setMethod("Math", "classA", Math.classA) x <- new("classA", log(1:10), realData = 1:10) stopifnot(identical(abs(x), 1:10)) setClass("classB", contains = "classA") y <- new("classB", x) stopifnot(identical(abs(y), abs(x))) # (version 2.9.0 or earlier fails here) ## an S3 generic: just for demonstration purposes f3 <- function(x, ...) UseMethod("f3") f3.default <- function(x, ...) "Default f3" ## S3 method (only) for classA f3.classA <- function(x, ...) "Class classA for f3" ## S3 and S4 method for numeric f3.numeric <- function(x, ...) "Class numeric for f3" setMethod("f3", "numeric", f3.numeric) ## The S3 method for classA and the closest inherited S3 method for classB ## are not found. f3(x); f3(y) # both choose "numeric" method ## to obtain the natural inheritance, set identical S3 and S4 methods setMethod("f3", "classA", f3.classA) f3(x); f3(y) # now both choose "classA" method ## Need to define an S3 as well as S4 method to use on an S3 object ## or if called from a package without the S4 generic MathFun <- function(x) { # a smarter "data.frame" method for Math group for (i in seq(length = ncol(x))[sapply(x, is.numeric)]) x[, i] <- (getFunction(.Generic))(x[, i]) x } setMethod("Math", "data.frame", MathFun) ## S4 method works for an S4 class containing data.frame, ## but not for data.frame objects (not S4 objects) try(logIris <- log(iris)) #gets an error from the old method ## Define an S3 method with the same computation Math.data.frame <- MathFun logIris <- log(iris)


“John is a student at Universidade de Aveiro, working on his thesis to get his master's degree in Computer Engineering and Telematics. His work consists in making experiences in order to maximize video streaming transmission rate and minimize loss of packets when moving between access points.”
“Marvin is a researcher at Instituto de Telecomunicações. His main work area is network protocols but he also supports PhD and master students with whatever help is necessary. Marvin is in charge of 5G research, in order to improve his performance until its deployment, and the AMazING system. ”
To speed up the testing process, a Node Configuration App with an intuitive interface will be created to facilitate the user to run any and as many experiments as he can, having benefits such as configuring wi-fi parameters in one or more nodes in the comfort of its desk.
Create a daemon, also known as a process working in the background of the OS, and making it run in every single node. This one will be connected to a REST API listening constantly for packages to arrive from the Node Configuration App. After the communication is processed, arguments will be passed to the daemon which interacts directly, through some libraries, with the wi-fi network adapter of the nodes where it is running and performing changes.
Create a Switch Controller App that allows the AMazING manager to enable and/or disable the switch PoE (Power over Ethernet) ports. This will permit nodes to be turned on or shutted down, extending their lifetime, making them more rentable and requiring only software updates, also available remotely.
One day John knew that a researcher had built a wonderful system that would allowed him to test his work in a more efficient way. Instead of asking that researcher to give him the node with the system inside or even passing him the system, he just opened the Node Configuration App and connected to the node where he knew that the was system running, did his own configurations and run his tests.
Working on his thesis John developed a system that predicts, using machine learning, which wi-fi channels are going to be busy or with most traffic. His objective is to automatically choose the best channel at real time to send his packets. In the confort of its desk he access the web app and performs all configurations needed on the nodes he desire to be on the same network, uses secure copy to send his work to one of the nodes and with ssh put that in execution.
As the person in charge of the AMazING system, Marvin needs to check every now and then the condition of the nodes. So, in order to maximize their lifetime he turns them off, using the switch controller system, when he knows that they are not being used.


Chief Investigator Johnny:
Mouen sent you? Damn it, this investigation is my responsibility. He should learn to trust me and quit doubting me. So what did he say?
"He said he wanted the results of the investigation as soon as possible."


Dear John Doe,
User foo-usr
just registered a new OAuth client under user foo-usr
on The Things Network.
Since user foo-usr
is not an admin, you need to approve this client before it can be used.
Client ID: foo-cli
Name: Foo Client
Description: Foo Client Description
Grants:
GRANT_AUTHORIZATION_CODE
authorization code
Rights:
RIGHT_USER_INFO
view user information
RIGHT_USER_APPLICATIONS_LIST
list applications the user is a collaborator of
RIGHT_USER_ORGANIZATIONS_LIST
list organizations the user is a member of
RIGHT_ORGANIZATION_INFO
view organization information
RIGHT_ORGANIZATION_APPLICATIONS_LIST
list the applications the organization is a collaborator of
RIGHT_APPLICATION_INFO
view application information
RIGHT_APPLICATION_SETTINGS_BASIC
edit basic application settings
RIGHT_APPLICATION_DEVICES_READ
view devices in application
RIGHT_APPLICATION_DEVICES_READ_KEYS
view device keys in application
RIGHT_APPLICATION_DEVICES_WRITE
create devices in application
RIGHT_APPLICATION_DEVICES_WRITE_KEYS
edit device keys in application
Redirect URIs:
https://example.com/oauth/callback
Logout Redirect URIs:
https://example.com/logout/success
You can use the command-line interface to approve (or reject) the OAuth client:
$ ttn-lw-cli clients set foo-cli \
--state APPROVED (or REJECTED) \
--state-description "..."
For more information on how to use the command-line interface, please refer to the documentation.


{% extends "small_base.html" %} {% block message %}
Your email {{user.email}} is already verified.
{% else %}Please verify your email before doing this action.
Check your email {{user.email}} (gmail.uw.edu • outlook.com) and click on the link from the email to verify. Please don't forget to check your spam box.
{% endif %}


| port (optional) - an integer value representing the port to be checked for joystick data |
|
Returns a float value between -1 and 1 that represents the V value of a joystick's output.
The optional port parameter allows you to select which joystick to get output from should you have multiple controllers connected to your PC. |
|
; JoyV Example
; ------------ While Not KeyDown(1) ; Get various joystick values ju#=JoyU() judir=JoyUDir() jv#=JoyV() jvdir=JoyVDir() jyaw#=JoyYaw() jpitch#=JoyPitch() jroll#=JoyRoll() ; Output joystick values Text 0,0,"Move joystick to output values onto screen" Text 0,20,"JoyU(): "+ju# Text 0,40,"JoyUDir(): "+judir Text 0,60,"JoyV(): "+jv# Text 0,80,"JoyVDir(): "+jvdir Text 0,100,"JoyYaw(): "+jyaw# Text 0,120,"JoyPitch(): "+jpitch# Text 0,140,"JoyRoll(): "+jroll# Flip Cls Wend |


Apple Special Event
Live from Brooklyn.
Watch on October 30 at 10 p.m. EDT.
Live from Brooklyn.
Watch on October 30 at 10 p.m. EDT.
Trade in your old device
for credit toward a new one.
Loose yourself in 50 million songs.
Try it free* Learn more >Wireless. Effortless. Magical.
Learn more > Buy >More power. More performance.
More pro.
Like a computer. Unlike any computer.
Learn more > Buy >


room floor heating
Path: CARNOT/loads
Purpose
Model of two rooms, separated by a wall. The rooms may be heated by a floor
heating.
Description
The beneath and above laying room are modelled as "virtual zones" with
a fixed temperature. For the description of the blocks, see THV_P_adapter, wall_out, floor_in, room_node.
Parameters and Dialog Box
Characteristics
Direct Feedthrough Yes
Sample
time
Inherited
from driving block
States
corresponding
to the number of nodes
Vectorized
No
Validation


Previously: Hexing the technical interview.
In the formless days, long before the rise of the Church, all spells were woven of pure causality, all actions were permitted, and death was common. Many witches were disfigured by their magicks, found crumpled at the center of a circle of twisted, glass-eaten trees, and stones which burned unceasing in the pooling water; some disappeared entirely, or wandered along the ridgetops: feet never touching earth, breath never warming air.
As a child, you learned the story of Gullveig-then-Heiðr, reborn three times from the fires of her trial, who traveled the world performing seidr: the reading and re-weaving of the future. Her foretellings (and there were many) were famed—spoken of even by the völva-beyond-the-world—but it was her survival that changed history. Through the ecstatic trance of seidr, she foresaw her fate, and conquered death. Her spells would never crash, and she became a friend to outcast women: the predecessors of your kind. It is said that Odin himself learned immortality from her.
To this day, all witches owe Heiðr a debt. Few delve into the ancient, unstructured magic nowadays. The very languages in which your spells are written are stabilized with seidr in their syntax, channeling the energies you summon through safe paths—more or less. There are still occasional explosions, of course. They’re just… more of the eyebrow-singeing variety, than the type that result in new and interestingly-shaped fjørds.
“Is everything all right?”
The interviewer—Criss, his badge says—is young, as is customary in the Valley. Wearing a hoodie which, judging from the lack of branding, cost at least three hundred dollars. He resembles no animal in particular, which gives you pause. Usually you’re better at that sort of thing.
“Do you mean in general? I don’t think so.” You look around at the conference room as if to confirm. The walls smell of Slack DMs and conflict avoidance.
“Ah, well, um. Yes, you’re probably right.” He sounds bashful. “But I’d like to do a little exercise with you nonetheless. Just a simple programming puzzle, so I can understand how you solve problems.”
Once, you solved a problem with a knife of shattered sky-glass. You wonder whether Criss would have the strength to do what you have done.
“Sooo… this problem is called N-Queens, and it’s fairly simple. Given an NxN chessboard, you need to find a way to place N queens on that board safely.”
You draw an eight-by-eight grid on the whiteboard, and neatly arrange eight queens together in the center. They face each other in a tight circle, to converse as equals.
“Er, no—that’s not right. See? This queen could kill any of these four, in one move.”
“Are you really unable,” you ask, voice as calm as stone, “to imagine eight powerful women in the same room without them trying to kill each other?”
“It’s… it’s just how the problem works.”
Perhaps they are the matriarchs of warring clans, then. Together to discuss a truce—but none trusting the other within a dagger’s reach. This too has happened, in the history of your kind.
“Can I use any language?”
“Sure.”
Move quickly, before he realizes his mistake.
{-# OPTIONS_GHC -fno-warn-missing-methods #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
“Oh, this is Haskell! I studied this in college!” He pauses, and frowns. “Undecidable instances?”
“We must use this,” you inform him cheerfully, “because Hask is not a category.”
“Oh, right.” He blusters a non-termination argument at nobody in particular. “That’s why we usually think in subsets of Haskell where types don’t have bottom values.”
“You could do that,” you concur, but, so quietly he cannot hear you, continue to believe the exact opposite.
nil = undefined
An uncomfortable question is coming. Head it off by blurting out the first thing that comes to mind. “To store our queen positions, we’ll need some kind of a linked list, right?”
“Sure, or a vector.”
“Lists are simpler.”
“OK, sure. Whatever floats your boat.”
Summon a linked list from the void. It floats to the surface of the screen: a timeless structure, expressed a thousand ways, but always beautiful. You sigh contentedly.
data Nil
data Cons x xs
“Couldn’t you use the built-in lists?” Criss asks, his brow furrowing.
“What?” You have no idea what he’s talking about. “Oh, no—not without pulling in a library. It’s easier to just define it inline.”
class First list x | list -> x
instance First Nil Nil
instance First (Cons x more) x
“The ‘class’ keyword defines a function signature,” you remind Criss, who seems to have forgotten something. “First takes a list and returns a value x from it. There are two instances of our function—Haskell uses pattern matching to choose which to call. First on a Nil list returns Nil, and First on a Cons cell returns that cell’s value, x.”
You let that sink in, and move to concatenating two lists together.
class ListConcat a b c | a b -> c
instance ListConcat Nil x x
instance (ListConcat as bs cs)
=> ListConcat (Cons a as) bs (Cons a cs)
“What’s the arrow?” Criss asks. Tell him it means implication. “To obtain the ListConcat after the arrow, we need the ListConcat before the arrow.”
Realization dawns. “Oh, right! This is recursion, because ListConcat appears in both positions. And the definition for Nil is the base case.”
“Exactly.” You’re so proud of Criss. He’s coming right along. “And here’s the generalized case, when we want to concatenate a list of lists.”
-- Concatenate all lists in a list
class ListConcatAll ls l | ls -> l
instance ListConcatAll Nil Nil
instance (ListConcat chunk acc result,
ListConcatAll rest acc)
=> ListConcatAll (Cons chunk rest) result
-- Is any element of this list True?
class AnyTrue list t | list -> t
instance AnyTrue Nil False
instance AnyTrue (Cons True more) True
instance (AnyTrue list t)
=> AnyTrue (Cons False list) t
This has required more concentration than you would have liked, so you back off to something easier. “Let’s do booleans,” you suggest, as if inviting him to lunch.
“Why?”
“Because we need them, of course.”
Seize two meaningless constants from the void, and imbue them with meaning.
data True
data False
class Not b1 b | b1 -> b
instance Not False True
instance Not True False
class Or b1 b2 b | b1 b2 -> b
instance Or True True True
instance Or True False True
instance Or False True True
instance Or False False False
Freyja would be pleased. To birth an algebra into the world is a beautiful thing.
“And I suppose we’ll need integral numbers to store the positions of our queens as well,” you mutter. “We’ll work in positive coordinates only, so the usual Peano construction should suffice.” Draw a thread of hair from your head, and tie a knot in it for zero.
data Z
data S n
type N0 = Z
type N1 = S N0
type N2 = S N1
type N3 = S N2
type N4 = S N3
type N5 = S N4
type N6 = S N5
type N7 = S N6
type N8 = S N7
“You’re… defining the natural numbers by hand? Why?”
“Haskell is for mathematicians,” you explain. “We always define our terms.”
-- Equality
class PeanoEqual a b t | a b -> t
instance PeanoEqual Z Z True
instance PeanoEqual (S a) Z False
instance PeanoEqual Z (S b) False
instance (PeanoEqual a b t)
=> PeanoEqual (S a) (S b) t
-- Comparison (<)
class PeanoLT a b t | a b -> t
instance PeanoLT Z Z False
instance PeanoLT (S x) Z False
instance PeanoLT Z (S x) True
instance (PeanoLT a b t)
=> PeanoLT (S a) (S b) t
-- Absolute difference
class PeanoAbsDiff a b c | a b -> c
instance PeanoAbsDiff Z Z Z
instance PeanoAbsDiff Z (S b) (S b)
instance PeanoAbsDiff (S a) Z (S a)
instance (PeanoAbsDiff a b c)
=> PeanoAbsDiff (S a) (S b) c
-- Integers from n to 0
class Range n xs | n -> xs
instance Range Z Nil
instance (Range n xs)
=> Range (S n) (Cons n xs)
“Wait, hang on,” Criss interrupts. “Shouldn’t you… shouldn’t there be type declarations here? At least on our functions?”
You smile kindly. “Haskell is a dynamically-typed, interpreted language.”
Criss appears to have swallowed a frog.
“Here, I’ll show you. Let’s check if one equals one.”
class LegalCompare t | -> t
where legalCompare :: t
instance (PeanoEqual (S Z) (S Z) t)
=> LegalCompare t
*Main> :type legalCompare
legalCompare :: True
“See? legalCompare
is equal to True
. Now let’s try writing an expression
that performs an invalid comparison. Say, comparing True to a List?”
class IllegalCompare t | -> t
where illegalCompare :: t
instance (PeanoEqual True (Cons Z False) t)
=> IllegalCompare t
“See? It loads just fine. It only breaks when you try to evaluate it—remember, Haskell is lazy.”
*Main> :type illegalCompare
illegalCompare :: PeanoEqual True (Cons Z False) t => t
“There you have it! A runtime type error.”
“It doesn’t say error…”
“Well, you know. Haskell’s error messages are notoriously difficult to understand.”
Criss appears quite ill. Take the opportunity to move on to higher order functions.
“Unfortunately, Haskell has no currying, so we’re forced to build our own tools for partial functions. Here’s a signature for generalized single-arity function application.”
class Apply f a r | f a -> r
“Just a function f which takes input a and returns r.” The variables have a lovely songlike melody. “For partial application, we could define datatypes like Partial1, Partial2, etc, but since we only need a few of these, it’s easier to define explicitly curried versions of the functions we need. Like so!”
data Conj1 list
instance Apply (Conj1 list) x (Cons x list)
Breathe deep, and allow your spirit to come unmoored from these concrete forms, ascending to the plane of higher order functions.
 Criss is still here, at least physically. Your laptop screen has turned a gorgeous mix of purples, owing to the extreme cold, but the code is still dimly visible within. It reminds you of a frozen lake at dusk. A liquid crystal.
“Criss. Criss.” He blinks rapidly, as if coming out of darkness. Such beautiful eyes. You remember when your own still held color. “We’re ready.”
“Yes. Right.”
“A queen is defined by her two coordinates on the board: x and y. We’ll also build a partially applied constructor for making queens with a given x coordinate.”
data Queen x y
data Queen1 x
instance Apply (Queen1 x) y (Queen x y)
-- A list of queens in row x with y from 0 to n.
class QueensInRow n x queens | n x -> queens
instance (Range n ys, Map (Queen1 x) ys queens)
=> QueensInRow n x queens
“Yes queens!” You murmur. This is, sadly, not that kind of interview.
These queens can stab in eight directions. You always assumed that was a metaphor.
-- Does queen a threaten queen b?
class Threatens a b t | a b -> t
instance (PeanoEqual ax bx xeq,
PeanoEqual ay by yeq,
Or xeq yeq xyeq,
PeanoAbsDiff ax bx dx,
PeanoAbsDiff ay by dy,
PeanoEqual dx dy deq,
Or xyeq deq res)
=> Threatens (Queen ax ay) (Queen bx by) res
-- Partial application of Threatens
data Threatens1 a
instance (Threatens a b t)
=> Apply (Threatens1 a) b t
A new queen enters the room, striding into position. She watches her adversaries warily, remaining just out of reach. Where can she stand? You envision a stack of universes—alternate worlds, each containing queens in various positions.
-- Is queen b compatible with all queen as?
class Safe config queen t | config queen -> t
instance (Map (Threatens1 queen) config m1,
AnyTrue m1 t1,
Not t1 t2)
=> Safe config queen t2
data Safe1 config
instance (Safe config queen t)
=> Apply (Safe1 config) queen t
-- Add a queen with the given x coordinate to a legal configuration, returning
-- a set of legal configurations.
class AddQueen n x c cs | n x c -> cs
instance (QueensInRow n x candidates,
Filter (Safe1 c) candidates filtered,
Map (Conj1 c) filtered cs)
=> AddQueen n x c cs
data AddQueen2 n x
instance (AddQueen n x c cs)
=> Apply (AddQueen2 n x) c cs
-- Add a queen at x to every configuration, returning a set of legal
-- configurations.
class AddQueenToAll n x cs cs' | n x cs -> cs'
instance (MapCat (AddQueen2 n x) cs cs')
=> AddQueenToAll n x cs cs'
“And now, we recur,” you whisper, and loop the spell back on itself, sewn together with the thread of control. One queen per row, in every legal position, for every configuration. You imagine what their startup’s about-us page would look like.
-- Add queens recursively
class AddQueensIf pred n x cs cs' | pred n x cs -> cs'
instance AddQueensIf False n x cs cs
instance (AddQueenToAll n x cs cs2,
AddQueens n (S x) cs2 cs')
=> AddQueensIf True n x cs cs'
class AddQueens n x cs cs' | n x cs -> cs'
instance (PeanoLT x n pred,
AddQueensIf pred n x cs cs')
=> AddQueens n x cs cs'
-- Solve
class Solution n c | n -> c where
solution :: n -> c
instance (AddQueens n Z (Cons Nil Nil) cs,
First cs c)
=> Solution n c where solution = nil
Criss has adopted the far-gaze of a man who has learned of some great loss, or perhaps been witness to a nearby explosion. Take his shoulder gently. “Psst!” You whisper. “All is prepared, and a solution is at hand.”
*Main> :type solution (nil :: N6)
solution (nil :: N6)
:: Cons (Queen (S (S (S (S (S Z))))) (S Z))
(Cons (Queen (S (S (S (S Z)))) (S (S (S Z))))
(Cons (Queen (S (S (S Z))) (S (S (S (S (S Z))))))
(Cons (Queen (S (S Z)) Z)
(Cons (Queen (S Z) (S (S Z)))
(Cons (Queen Z (S (S (S (S Z)))))
Nil)))))
Look: the pretty-printer has aligned things just so, creating a lovely line of zeroes along the vertical axis. “So that’s a queen at 5,1, at 4,3, at 3,5, at 2,0, 1,2, and 0,4. Does that work, Criss?”
Criss stares at you for a long, long moment. “You never… you never wrote an actual value. You… do realize that the type system is meant to constrain values, right?”
“No,” you inform him, matter-of-factly. “No, that doesn’t sound right.”
He leans back in his chair, so far you think he may fall over, and rubs his forehead with both hands. You, who through seidr, have seen your rejection email already, know what he is about to say.
“We’ll be in touch.”
With sincerest thanks to Patrick Thomson, and Conrad Parker’s Type Level Instant Insanity.
If this was a book - I’d buy it.
Absolutely delightful.
Please let us read that kind of interview next.
It cannot be ran in ghci unless you define booleans before
AnyTrue
.Wunderbar.
This is so good, but you have a typo. It’s spelled “murmur”.
Aaaand now I want to translate this into a C++ template metaprogram.
This is great! I’d love to read more.
A genuine pleasure to read. Well done!
I’d buy the book and then another one for the office and the ebook and the hardcover. Masterpiece
This is beautiful in the most hideous way possible.
I’d buy the book too!
Reminds me of why the lucky stiff.
This is fantastic. Well done.
This was absolutely amazing!
It is so beautiful, it brings a tear of ecstasy to the jaded eye of this humble mathematician.
I read this during the intermediate Passover days. I smiled at the end and thought of Proverbs 5:20
המַיִם עֲמֻקִּים עֵצָה בְלֶב אִישׁ וְאִישׁ תְּבוּנָה יִדְלֶנָּה:
“Counsel in man’s heart is like deep water, but a man of understanding will draw it out.”
Rav ABY taught me: ‘The way of the wise man is to conceal his counsel in the depths of his heart (deep beneath the surface of his words), making it hard for others to grasp it. His counsel is like waters that lie deep beneath the surface of the earth and are hard to draw out. But “a man of understanding will draw it out”: he starts by drawing out the upper waters – seeking to understand the surface meaning – and this will bring him to what lies below (Metzudas David).
Superbly designed piece. May you go from strength to strength.

A few more of these, and it’d make a great book. I’d definitely buy it and put it on the shelf at home and at work.
Could you have made some of the code cleaner by using TypeFamily?
Great blog
Nice article, your just described it beautiful and easy way, thank you for sharing.
This was art. Very, very fine art.  Thank you!
This is poetry. I enjoyed it very much even though I didn’t understand it all.
Please write a book. I will buy it.


--- layout: post title: Fabindia - Jasmine calming and rejuvenating soap tags: - Fabindia status: publish type: post published: true meta: _edit_last: '2' _graphene_slider_img: global _graphene_slider_imgurl: '' _graphene_show_addthis: global al2fb_facebook_image_id: '1126' _aioseop_title: Fabindia - Jasmine calming and rejuvenating soap _aioseop_keywords: Fabindia - Jasmine calming and rejuvenating soap al2fb_facebook_link_id: '218440691518395_251247828237681' al2fb_facebook_link_time: '2011-07-29T09:47:40+00:00' al2fb_facebook_link_picture: meta=http://missenchanted.com/wp-content/uploads/2011/07/IMG_1175-150x150.jpg _yoast_wpseo_linkdex: '0' _thumbnail_id: '1126' ---
After My LUSH Karma experience, I thought of moving on to a cheaper alternative and plus I love trying new products :), I lay my hands on Fabindia soaps.  I have been facing a lot of dryness, which Lush Karma also could not resolve.My first try is the Fabindia Jasmine soap.
Price: Rs. 65 for 100gm Product claims: Calming and rejuvenating soap made using jasmine oil. Product contains: Soap Base (Sodium Cocoate, Sodium Stearate, Water, Propylene Glycol, Sugar, Sodium Lauryl Ether Sulphate, Sodium Chloride, Disodium EDTA and BHT), Glycerine, Castor Oil, Aloe Vera, Jasmine Absolute. What I like about the product:


Young Man Who Leaked Sex Tape That Led To Expulsion Of Babcock Female Student, Tenders Apology
by Faderera FaladeThe twitter user who posted the Viral video of BABCOCK Sex tape has Issued an apology.
Recall Naija News last week reported that a female student of BABCOCK was expelled from school after a viral video in which she was having sex with another student who had been rusticated from the school.
Laolu who posted the video has now tendered an apology online and stated his regrets in the whole matter but Nigerians have taken the opportunity to rather blast them.
See his apology below:


Lotka-Volterra Species Competition
Check this video for further clarification:
https://youtu.be/obasfCufOr0
Carrying Capacity Species 1
Carrying Capacity Species 2
Competition Coefficient Species 1
Competition Coefficient Species 2
Crosspoint:
0


{%load static%}
Document
PMO DASHBOARD
当前时间：2020年3月17-0时54分14秒
Projects by BU
Projects by stage
North
South
East&West
Wuxi
{{project_num}}
{{COGS}}
Total Projects
COGS(MRMB)
{{productivity}}
{{CAPEX}}
Productivity(MRMB)
CAPEX(MRMB)
Projects by type
Projects by region
COGS by BU


Using a sharp knife, prick the leg of lamb all over, about 20 times and about 2cm/1in deep.
Cut the garlic cloves into thin strips and place one slice of garlic into each hole with a few rosemary leaves. Continue until all the holes are full. Season with salt and freshly ground black pepper and drizzle with oil.
Place the lamb directly onto the oven rack and place a roasting tray directly underneath on the rack below. This is to catch the fat as it drips from the lamb. Roast in the pre-heated oven for 1 hour 15 minutes or until cooked to taste, basting frequently.
Par-boil the potatoes. Drain them, then return them to the pan and shake to roughen the edges.
After the first 15-20 minutes of cooking the lamb, carefully tip the potatoes into the roasting tray underneath the lamb, which will now contain the hot fat from the lamb above.
Coat the potatoes in the fat then roast with the lamb until golden and cooked through, turning once or twice.
To make the pesto, put all the ingredients for the coriander pesto, except the oil and seasoning, into a food processor. Blend, gradually adding oil until you reach the desired consistency. Season with salt and freshly ground black pepper. Serve with the lamb and roast potatoes.


Statistical models and utilities for the analysis of word frequency distributions. The utilities include functions for loading, manipulating and visualizing word frequency data and vocabulary growth curves. The package also implements several statistical models for the distribution of word frequencies in a population. (The name of this package derives from the most famous word frequency distribution, Zipf's law.)
| Version: | 0.6-10 |
| Depends: | R (≥ 3.0.0) |
| Imports: | methods, utils, stats, graphics, grDevices |
| Published: | 2017-08-17 |
| Author: | Stefan Evert, Marco Baroni |
| Maintainer: | Stefan Evert <stefan.evert at fau.de> |
| License: | GPL-3 |
| URL: | http://zipfR.R-Forge.R-project.org/ |
| NeedsCompilation: | no |
| Citation: | zipfR citation info |
| Materials: | README NEWS |
| In views: | Distributions, NaturalLanguageProcessing |
| CRAN checks: | zipfR results |
| Reference manual: | zipfR.pdf |
| Vignettes: |
zipfR Tutorial |
| Package source: | zipfR_0.6-10.tar.gz |
| Windows binaries: | r-devel: zipfR_0.6-10.zip, r-release: zipfR_0.6-10.zip, r-oldrel: zipfR_0.6-10.zip |
| OS X binaries: | r-release: zipfR_0.6-10.tgz, r-oldrel: zipfR_0.6-10.tgz |
| Old sources: | zipfR archive |
| Reverse depends: | stratifyR |
| Reverse imports: | MetaLandSim, qGaussian |
| Reverse suggests: | languageR |
Please use the canonical form https://CRAN.R-project.org/package=zipfR to link to this page.


Tutorial Example¶
In this section, we explain the examples from Tutorial/ directory but you can see most sophisticated implemented cases:
- Tutorial/main1.py The most basic case: cloud allocation, and minimum path routing,
- Tutorial/main2.py Using first case, we scale the modules in the cloud and we use a round robin scheduler.
- Tutorial/main3.py Using second case, we show how to implement a dynamic control
- VRGameFog-IFogSim-WL/main.py This implemention have been used to compare YAFS simulator with iFogSim, implementing a close setup of the experiments.
- FogCentrality/experiment1.py In this case, we have analysed how the topology and the allocation of modules affects in the latency time.
- FogCentrality/experiment2.py
- DynamicAllocation/.py It is a demo of how to implement a dynamic allocation of modules according a customized distribution. We use a random euclidean network from a Graphml format, and several selection, population, and allocation implementations.
- DynamicFailuresOnNodes/main.py From a euclidean random network we dynamically remove nodes.
- DynamicWorkload/main.py In this case, we simulate the movement of users in the network. In each step of the customized distribution nodes are allocated in the next node of the path to reach the point on all modules are.
TODO Explain with detail the first three cases.


Tracker
Information
Sessions
Heatmap
Statistics
Sign out
Filter
Start From:
Ending At:
Orchard
Farm
Worker
Foreman
Update Heatmap


{% extends "layout.html" %} {% block page_title %} Collections - Local Authorities {% endblock %} {% block content %} Collection Local Authorities Discover data about local councils, spending figures, land planning, or reserves, plus much more Local councils List of Town and Parish Councils in England View data Spending figures Staffordshire County Council expenditure over £500 View data Land planning Planning application data for Wolverhampton City Council, published as part of the incentive scheme. View data Reserves National nature reserves (England) View data {% endblock %}
Discover data about local councils, spending figures, land planning, or reserves, plus much more
List of Town and Parish Councils in England
Staffordshire County Council expenditure over £500
Planning application data for Wolverhampton City Council, published as part of the incentive scheme.
National nature reserves (England)


1 2 3 4 5 6 7 8 9 10 11 12
13 14 15
16
17 /*!
18 * ======== Log ========
19 * Event logging manager
20 *
21 * RTSC modules and the application code generate `{@link #Event Log_Event}`
22 * events by calling the `Log` module's functions. The `Log` module then
23 * passes those events to an `{@link ILogger}` instance assigned to the event
24 * originating module, specified by that module's configuration parameter
25 * `common$.logger`. `ILogger` instances handle events, usually converting
26 * events to `{@link #EventRec Log_EventRec}` records prior to recording,
27 * transmitting, or displaying them.
28 *
29 * All events generated by a target module are stored and displayed by an
30 * `ILogger`, examples of which are instances of
31 * `{@link LoggerBuf xdc.runtime.LoggerBuf}` or
32 * `{@link LoggerSys xdc.runtime.LoggerSys}`. At runtime, modules
33 * generate events through this module, rather than invoking directly their
34 * `ILogger`s. By doing so, modules can be configured to use different
35 * `ILogger` implementations without any changes to their source code.
36 *
37 * A logger instance can accept `Log` events from any module, but a module
38 * can put `Log` events to only one logger instance. There can be one or
39 * more logger instances in a system. All `Log` calls that are not in a
40 * module are controlled by the module `{@link Main xdc.runtime.Main}`.
41 * For example, top-level application code or any existing sources that
42 * simply call the `Log` or `Assert` methods implicitly use the logger
43 * associated with the `Main` module.
44 *
45 * The generation of a `Log` event is controlled by a module's diagnostics
46 * mask, which is described in details in `{@link Diags}`. Each `Log` event
47 * is associated with a mask. `Log` events are generated only when a
48 * particular bit is set in both the `Log` event mask and the module's
49 * diagnostics mask. For example, a `Log` event mask with the
50 * `{@link Diags#USER1 USER1}` bit set is generated only when the `USER1`
51 * bit is also set in the module's diagnostics mask.
52 *
53 * There are two ways to generate `Log` events:
54 *
55 * @p(blist)
56 * - `{@link #write8 Log_write()}`, which is tailored for module writers
57 * and takes full advantage of the XDC configuration model. For example,
58 * the message string associated with the `Log` event need not be a part of
59 * the final application, significantly reducing the "footprint overhead"
60 * of embedding diagnostics in deployed systems. The `Log_write[0-8]()`
61 * functions allow up to 8 values to be passed to the logger. They expect
62 * the logger to handle any formatting. A `Log` event type allows you to
63 * specify the type of event.
64 * - `{@link #print6 Log_print()}`, which is designed for arbitrary C code.
65 * The `Log_print[0-6]()` functions allow up to 6 values to be passed along
66 * with a printf-like format string to the logger. They handle printf-style
67 * formatting.
68 * @p
69 *
70 * Both functions are controlled by the module's diagnostics mask. Their
71 * storage or output is defined by the logger that is assigned to the
72 * module that calls the `Log` methods or to the
73 * `{@link Main xdc.runtime.Main}` module if the caller is not part of a
74 * module.
75 *
76 * The `Log` function call sites are implemented in such a way that an
77 * optimizer can completely eliminate `Log` code from the program if the
78 * `Log` functions have been permanently disabled at configuration time. If
79 * the `Log` functions are permanently turned on at configuration time,
80 * then the optimizer can eliminate all runtime conditional checking and
81 * simply invoke the `Log` functions directly. Runtime checking is performed
82 * only when the `Log` functions are configured to be runtime modifiable.
83 *
84 * The Log calls can also be completely removed by defining the symbol
85 * `xdc_runtime_Log_DISABLE_ALL`. This can be done on the compile line, e.g.
86 * `-Dxdc_runtime_Log_DISABLE_ALL`. This will completely remove the `Log`
87 * statements from any code compiled with this flag, regardless of the
88 * application's logging configuration or your compiler's optimization
89 * settings.
90 *
91 * It is also possible to remove all logging except for
92 * `{@link #error Log_error}`, `{@link #warning Log_warning}`, or
93 * `{@link #info Log_info}` statements. This is done by first defining
94 * `xdc_runtime_Log_DISABLE_ALL`, followed by defining one or more of the
95 * symbols below to leave that type of logging enabled:
96 * @p(blist)
97 * - `xdc_runtime_Log_ENABLE_ERROR`
98 * - `xdc_runtime_Log_ENABLE_WARNING`
99 * - `xdc_runtime_Log_ENABLE_INFO`
100 * @p
101 * For example, to disable all `Log` statements except for `Log_error`, add
102 * the following to the compile line:
103 * @p(code)
104 * -Dxdc_runtime_Log_DISABLE_ALL -Dxdc_runtime_Log_ENABLE_ERROR
105 * @p
106 *
107 * @a(Examples)
108 * Example 1: The following example defines a `Log` event, uses that `Log`
109 * event in a module, and configures the program to generate the `Log`
110 * event. In this example, both `USER1` and `USER2` bits are set in the
111 * event mask. This means that if either bit is set in the module's
112 * diagnostics mask, then the `Log` event will be generated.
113 *
114 * This is a part of the XDC specification file for the `Mod` module
115 * (Mod.xdc):
116 *
117 * @p(code)
118 * import xdc.runtime.Diags;
119 * import xdc.runtime.Log;
120 *
121 * config Log.Event L_someEvent = {
122 * mask: Diags.USER1 | Diags.USER2,
123 * level: Diags.LEVEL1,
124 * msg: "my log event message, arg1: 0x%x, arg2: 0x%x"
125 * };
126 * @p
127 *
128 * This is a part of the C code implementation of the Mod module:
129 *
130 * @p(code)
131 * #include <xdc/runtime/Log.h>
132 * UInt x, y;
133 *
134 * Log_write2(Mod_L_someEvent, (IArg)x, (IArg)y);
135 * @p
136 *
137 * The following configuration script demonstrates how the application might
138 * control the `Log` statements embedded in the `Mod` module at configuration
139 * time. In this case, the configuration script arranges for the `Log`
140 * statements within the `Mod` module (shown above) to always generate events.
141 * Without these configuration statements, no `Log` events would be generated
142 * by this module.
143 *
144 * This is part of the XDC configuration file for the application:
145 *
146 * @p(code)
147 * var Diags = xdc.useModule('xdc.runtime.Diags');
148 * var LoggerSys = xdc.useModule('xdc.runtime.LoggerSys');
149 * var Mod = xdc.useModule('my.pkg.Mod');
150 * Mod.common$.diags_USER1 = Diags.ALWAYS_ON;
151 * Mod.common$.logger = LoggerSys.create();
152 * @p
153 *
154 * @p(html)
155 *

156 * @p
157 *
158 * Example 2: The following XDC configuration statements turn on enter
159 * and exit logging at configuration time for a module. Without any other
160 * changes in the runtime code, every time a module `Mod`'s function is
161 * being called or exits, an event will be logged.
162 *
163 * @p(code)
164 * var Diags = xdc.useModule('xdc.runtime.Diags');
165 * var Mod = xdc.useModule('my.pkg.Mod');
166 *
167 * Mod.common$.diags_ENTER = Diags.ALWAYS_ON;
168 * Mod.common$.diags_EXIT = Diags.ALWAYS_ON;
169 * @p
170 *
171 * @p(html)
172 *

173 * @p
174 *
175 * Example 3: The following example configures a module to support enter and
176 * exit logging, but defers the actual activation and deactivation of the
177 * logging until runtime. See the `{@link Diags#setMask Diags_setMask()}`
178 * function for details on specifying the control string.
179 *
180 * This is a part of the XDC configuration file for the application:
181 *
182 * @p(code)
183 * var Diags = xdc.useModule('xdc.runtime.Diags');
184 * var Mod = xdc.useModule('my.pkg.Mod');
185 *
186 * Mod.common$.diags_ENTER = Diags.RUNTIME_OFF;
187 * Mod.common$.diags_EXIT = Diags.RUNTIME_OFF;
188 * @p
189 *
190 * This is a part of the C code for the application:
191 *
192 * @p(code)
193 * // turn on enter and exit logging in the module
194 * Diags_setMask("my.pkg.Mod+EX");
195 *
196 * // turn off enter and exit logging in the module
197 * Diags_setMask("my.pkg.Mod-EX");
198 * @p
199 */
200
201 @CustomHeader
202 @DirectCall
203
204 module Log {
205
206 /*!
207 * ======== NUMARGS ========
208 * Maximum number of arguments supported in `Log` events.
209 */
210 const Int NUMARGS = 8;
211
212 /*!
213 * ======== PRINTFID ========
214 * The `EventId` for `Log_print()` events
215 */
216 const EventId PRINTFID = 0;
217
218 /*!
219 * ======== EventDesc ========
220 * `Log` event descriptor
221 *
222 * Each `Log` event is defined by a `Log` event descriptor.
223 *
224 * The `mask` defines which bits in the module's diagnostics mask
225 * enable this `Log` event. Events "posted" via `Log_write` are only
226 * written to the underlying logger if one of the mask's bits matches
227 * the caller's module diagnostics settings (see
228 * `{@link xdc.runtime.Types#common$}`).
229 *
230 * The 'level' defines the event level of the event. While the diags
231 * bits selected in the 'mask' signify the "category" of the event (e.g.
232 * Entry/Exit, Analysis, Info), the 'level' field allows you to assign
233 * a "priority" or "detail level" to the event relative to other events in
234 * that category. There are four event levels defined by
235 * '{@link xdc.runtime.Diags#EventLevel}'.
236 *
237 * Filtering of events by level is handled by the ILogger implementation.
238 * ILogger implementations which also implement the {@link IFilterLogger}
239 * interface support filtering of events based on priority level.
240 *
241 * Specifying an event level is optional. Events that don't specify a
242 * level will receive Diags.LEVEL1 by default, making them the highest
243 * priority and ensuring that they will not inadvertently be filtered out
244 * by level-based filtering.
245 *
246 * The `msg` defines a printf style format string that defines how to
247 * render the arguments passed along the event in a `Log_write` call.
248 * For a description of the allowable format strings see
249 * `{@link #print6}`.
250 *
251 * @see #write8
252 * @see #print6
253 */
254 metaonly struct EventDesc {
255 Diags.Mask mask; /*! event enable mask */
256 Diags.EventLevel level; /*! event level relative to other events */
257 String msg; /*! event "printf" message format string */
258 };
259
260 /*!
261 * ======== EventRec ========
262 * The target representation of a recorded event
263 *
264 * This structure defines how events are recorded on the target.
265 */
266 struct EventRec {
267 Types.Timestamp64 tstamp; /*! time event was written */
268 Bits32 serial; /*! serial number of event */
269 Types.Event evt; /*! target encoding of an Event */
270 IArg arg[NUMARGS]; /*! arguments passed via Log_write/print */
271 }
272
273 /*!
274 * ======== Event ========
275 * `Log` event type
276 *
277 * An `Event` is represented on the target as a 32-bit value that can
278 * be decoded offline to recover the `Event` information defined in
279 * a corresponding metaonly `EventDesc`. In addition, `Event`s may be
280 * decoded at runtime via methods provided in this module; see
281 * `{@link #getMask}` and `{@link #getEventId}`.
282 *
283 * When an event is "raised" a `{@link Types#Event Types_Event}` is
284 * created which has the same event ID as the `Log_Event` but also
285 * encodes the module ID of the caller. This new event is passed to
286 * the underlying `{@link ILogger}` module along with any arguments
287 * associated with the event.
288 *
289 * @see #getMask
290 * @see #getEventId
291 */
292 @Encoded typedef EventDesc Event;
293
294 /*!
295 * ======== EventId ========
296 * Unique ID embedded in each `{@link #Event}`
297 *
298 * This ID must be used to compare two `Event`s for equality. Event
299 * ids are not guaranteed to remain constant between different
300 * configurations of an application. For example, adding a module
301 * may cause the event ids of another module to change.
302 *
303 * However, event ids declared by a module are guaranteed to be
304 * consecutive values starting from the first declared
305 * `{@link #Event Log_Event}` and increasing to the last declared
306 * event. As a result, clients of a module can efficiently test ranges
307 * of events and modules can add new events, such as internal trace
308 * events, without breaking clients; simply be careful to add new events
309 * after any existing events in you module's `.xdc` specification.
310 *
311 * @see #getEventId
312 * @see #Event
313 */
314 typedef Types.RopeId EventId;
315
316 /*!
317 * ======== L_construct ========
318 * Lifecycle event posted when an instance is constructed
319 */
320 config Log.Event L_construct = {
321 mask: Diags.LIFECYCLE,
322 msg: "<-- construct: %p('%s')"
323 };
324
325 /*!
326 * ======== L_create ========
327 * Lifecycle event posted when an instance is created
328 */
329 config Log.Event L_create = {
330 mask: Diags.LIFECYCLE,
331 msg: "<-- create: %p('%s')"
332 };
333
334 /*!
335 * ======== L_destruct ========
336 * Lifecycle event posted when an instance is destructed
337 */
338 config Log.Event L_destruct = {
339 mask: Diags.LIFECYCLE,
340 msg: "--> destruct: (%p)"
341 };
342
343 /*!
344 * ======== L_delete ========
345 * Lifecycle event posted when an instance is deleted
346 */
347 config Log.Event L_delete = {
348 mask: Diags.LIFECYCLE,
349 msg: "--> delete: (%p)"
350 };
351
352 /*!
353 * ======== L_error ========
354 * Error event posted by Log_errorX API
355 *
356 * This event is marked as a STATUS event and given the priority level
357 * of ERROR.
358 *
359 * This event prints the Log call site (%$F) and a format string (%$S)
360 * which is recursively formatted with any additional arguments.
361 */
362 config Log.Event L_error = {
363 mask: Diags.STATUS,
364 level: Diags.ERROR,
365 msg: "ERROR: %$F%$S"
366 };
367
368 /*!
369 * ======== L_warning ========
370 * Warning event posted by Log_warningX API
371 *
372 * This event is marked as a STATUS event and given the priority level of
373 * WARNING.
374 *
375 * This event prints the Log call site (%$F) and a format string (%$S)
376 * which is recursively formatted with any addition arguments.
377 */
378 config xdc.runtime.Log.Event L_warning = {
379 mask: Diags.STATUS,
380 level: Diags.WARNING,
381 msg: "WARNING: %$F%$S"
382 };
383
384 /*!
385 * ======== L_info ========
386 * Info event posted by Log_infoX API
387 *
388 * This event is marked as an INFO event. The event priority is not
389 * specified in the event definition. Rather, it is specified as an
390 * argument to the Log_infoX APIs.
391 *
392 * This event prints the Log call site (%$F) and a format string (%$S)
393 * which is recursively formatted with any addition arguments.
394 */
395 config xdc.runtime.Log.Event L_info = {
396 mask: Diags.INFO,
397 msg: "%$F%$S"
398 };
399
400 /*!
401 * ======== L_start ========
402 * Benchmark event used to log the start of an operation
403 * @_nodoc
404 *
405 * @a(Example)
406 * The following C code shows how to log a simple
407 * benchmark 'start' event along with a user-specified
408 * format string describing the event.
409 *
410 * @p(code)
411 * #include <xdc/runtime/Log.h>
412 * ...
413 * Log_write2(Log_L_start, (IArg)"My benchmark event", (IArg)myUniqueId);
414 * Log_write2(Log_L_stop, (IArg)"My benchmark event", (IArg)myUniqueId);
415 * @p
416 *
417 * @param(fmt) a constant string that provides format specifiers for
418 * up to 6 additional parameters
419 * @param(id) a unique ID used to match benchmark start and stop
420 * events
421 */
422 config xdc.runtime.Log.Event L_start = {
423 mask: Diags.ANALYSIS,
424 msg: "Start: %$S"};
425
426 /*!
427 * ======== L_stop ========
428 * Benchmark event used to log the end of an operation
429 * @_nodoc
430 *
431 * @a(Example)
432 * The following C code shows how to log a simple
433 * benchmark 'stop' event along with a user-specified
434 * format string describing the event.
435 *
436 * @p(code)
437 * #include <xdc/runtime/Log.h>
438 * ...
439 * Log_write2(Log_L_start, (IArg)"My benchmark event", (IArg)myUniqueId);
440 * Log_write2(Log_L_stop, (IArg)"My benchmark event", (IArg)myUniqueId);
441 * @p
442 *
443 * @param(fmt) a constant string that provides format specifiers for
444 * up to 6 additional parameters
445 * @param(id) a unique ID used to match benchmark start and stop
446 * events
447 */
448 config xdc.runtime.Log.Event L_stop = {
449 mask: Diags.ANALYSIS,
450 msg: "Stop: %$S"};
451
452 /*!
453 * ======== L_startInstance ========
454 * Benchmark event used to log the start of an operation instance
455 * @_nodoc
456 *
457 * Event parameter provides instance data to differentiate
458 * between multiple instances that can run in parallel.
459 *
460 * @a(Example)
461 * The following C code shows how to log a benchmark
462 * 'startInstance' event along with a user-specified
463 * instance identifier and a format string describing the event.
464 *
465 * @p(code)
466 * #include <xdc/runtime/Log.h>
467 * ...
468 * Log_write3(Log_L_startInstance, (IArg)"My benchmark event", (IArg)uniqueId, (IArg)instId);
469 * ...
470 * Log_write3(Log_L_stopInstance, (IArg)"My benchmark event", (IArg)uniqueId, (IArg)instId);
471 * @p
472 *
473 * @param(fmt) a constant string that provides format specifiers for
474 * up to 6 additional parameters
475 * @param(id) a unique ID used to match benchmark start and stop
476 * events
477 * @param(instId) a unique instance ID that can be used to match
478 * instance events
479 */
480 config xdc.runtime.Log.Event L_startInstance = {
481 mask: Diags.ANALYSIS,
482 msg: "StartInstance: %$S"
483 };
484
485 /*!
486 * ======== L_stopInstance ========
487 * Benchmark event used to log the end of an operation instance
488 * @_nodoc
489 *
490 * Event parameter provides instance data to differentiate
491 * between multiple instances that can run in parallel.
492 *
493 * @a(Example)
494 * The following C code shows how to log a benchmark
495 * 'stopInstance' event along with a user-specified
496 * instance identifier and a format string describing the event.
497 *
498 * @p(code)
499 * #include <xdc/runtime/Log.h>
500 * ...
501 * Log_write3(Log_L_startInstance, (IArg)"My benchmark event", (IArg)uniqueId, (IArg)instId);
502 * ...
503 * Log_write3(Log_L_stopInstance, (IArg)"My benchmark event", (IArg)uniqueId, (IArg)instId);
504 * @p
505 *
506 * @param(fmt) a constant string that provides format specifiers for
507 * up to 6 additional parameters
508 * @param(id) a unique ID used to match benchmark start and stop
509 * events
510 * @param(instId) a unique instance ID that can be used to match
511 * instance events
512 */
513 config xdc.runtime.Log.Event L_stopInstance = {
514 mask: Diags.ANALYSIS,
515 msg: "StopInstance: %$S"
516 };
517
518 /*!
519 * ======== getMask ========
520 * Get the `Diags` mask for the specified (encoded) event
521 *
522 * @param(evt) the `Log` event encoding a mask and event ID
523 *
524 * @a(returns) `Diags` mask for the specified event
525 */
526 @Macro Diags.Mask getMask(Event evt);
527
528 /*!
529 * ======== getRope ========
530 * Get RopeId of the Event.msg for the specified (encoded) event
531 * @_nodoc
532 */
533 @Macro Text.RopeId getRope(Event evt);
534
535 /*!
536 * ======== getEventId ========
537 * Get event ID of the specified (encoded) event
538 *
539 * This method is used to compare "known" `Log` events with
540 * "raised" `{@link Types#Event Types_Event}`.
541 *
542 * @param(evt) the `Log` event encoding a mask and event ID
543 *
544 * @a(returns) event ID of the specified event
545 *
546 * @see Types#getEventId
547 */
548 @Macro EventId getEventId(Event evt);
549
550 /*!
551 * ======== print0 ========
552 * Generate a `Log` "print event" with 0 arguments
553 *
554 * @see #print6
555 */
556 @Macro Void print0(Diags.Mask mask, CString fmt);
557
558 /*!
559 * ======== print1 ========
560 * Generate a `Log` "print event" with 1 argument
561 *
562 * @see #print6
563 */
564 @Macro Void print1(Diags.Mask mask, CString fmt, IArg a1);
565
566 /*!
567 * ======== print2 ========
568 * Generate a `Log` "print event" with 2 arguments
569 *
570 * @see #print6
571 */
572 @Macro Void print2(Diags.Mask mask, CString fmt, IArg a1, IArg a2);
573
574 /*!
575 * ======== print3 ========
576 * Generate a `Log` "print event" with 3 arguments
577 *
578 * @see #print6
579 */
580 @Macro Void print3(Diags.Mask mask, CString fmt, IArg a1, IArg a2,
581 IArg a3);
582
583 /*!
584 * ======== print4 ========
585 * Generate a `Log` "print event" with 4 arguments
586 *
587 * @see #print6
588 */
589 @Macro Void print4(Diags.Mask mask, CString fmt, IArg a1, IArg a2,
590 IArg a3, IArg a4);
591
592 /*!
593 * ======== print5 ========
594 * Generate a `Log` "print event" with 5 arguments
595 *
596 * @see #print6
597 */
598 @Macro Void print5(Diags.Mask mask, CString fmt, IArg a1, IArg a2,
599 IArg a3, IArg a4, IArg a5);
600
601 /*!
602 * ======== print6 ========
603 * Generate a `Log` "print event" with 6 arguments
604 *
605 * As a convenience to C (as well as assembly language) programmers,
606 * the `Log` module provides a variation of the ever-popular `printf`
607 * function.
608 * The `print[0-6]` functions generate a `Log` "print event" and route
609 * it to the current module's logger.
610 *
611 * The arguments passed to `print[0-6]` may be characters, integers,
612 * strings, or pointers. However, because the declared type of the
613 * arguments is `{@link xdc IArg}`, all pointer arguments must be cast
614 * to an `IArg` type. `IArg` is an integral type large enough to hold
615 * any pointer or an `int`. So, casting a pointer to an `IArg` does
616 * not cause any loss of information and C's normal integer conversions
617 * make the cast unnecessary for integral arguments.
618 *
619 * The format string can use the following conversion characters.
620 * However, it is important to recall that all arguments referenced by
621 * these conversion characters have been converted to an `IArg`
622 * prior to conversion; so, the use of "length modifiers" should be
623 * avoided.
624 *
625 * @p(code)
626 * Conversion Character Description
627 * ------------------------------------------------
628 * %c Character
629 * %d Signed integer
630 * %u Unsigned integer
631 * %x Unsigned hexadecimal integer
632 * %o Unsigned octal integer
633 * %s Character string
634 * %p Pointer
635 * %f Single precision floating point (float)
636 * @p
637 *
638 * Format strings, while very convenient, are a well known source of
639 * portability problems: each format specification must precisely match
640 * the types of the arguments passed. Underlying "printf" functions use
641 * the format string to determine how far to advance through their
642 * argument list. For targets where pointer types and integers are the
643 * same size there are no problems. However, suppose a target's pointer
644 * type is larger than its integer type. In this case, because integer
645 * arguments are widened to be of type `IArg`, a format specification of
646 * "%d" causes an underlying `printf()` implementation to read the
647 * extended part of the integer argument as part of the next argument(!).
648 *
649 * To get around this problem and still allow the use of "natural"
650 * format specifications (e.g., `%d` and `%x` with optional width
651 * specifications), `{@link System#aprintf()}` is used which assumes
652 * that all arguments have been widened to be of type `IArg`.
653 *
654 * See `{@link System#printf}` for complete details.
655 *
656 * The `%f` format specifier is used to print a single precision float
657 * value. Note that `%f` assumes that sizeof(Float) <= sizeof(IArg).
658 * Most clients that interpret float values expect that they are
659 * represented in IEEE 754 floating point format. Therefore, it is
660 * recommended that the float values be converted into that format prior
661 * to supplying the values to `Log` functions in cases where targets do
662 * not generate the float values in IEEE 754 floating point format by
663 * default.
664 *
665 * The first argument to a `Log_print` call is the diags category to be
666 * associated with the event.
667 *
668 * It is also possible to associate an event level with the event to
669 * enable filtering of events based on event level. Conceptually, it is
670 * best to regard the event level as completely separate from the event's
671 * diags category; however, the priority value actually occupies a part
672 * of the diags mask. For this reason, it is possible to specify an event
673 * level by OR'ing the level with the diags mask. For example, to print
674 * an `Diags_INFO` event of `Diags_LEVEL2`, you'd simply write:
675 * (Diags_INFO | Diags_LEVEL2)
676 *
677 * Specifying an event level is optional. `Log_print` calls which do not
678 * specify a level will receive the highest priority by default.
679 *
680 * @param(mask) enable bits and optional detail level for this event
681 * @param(fmt) a `printf` style format string
682 * @param(a1) value for first format conversion character
683 * @param(a2) value for second format conversion character
684 * @param(a3) value for third format conversion character
685 * @param(a4) value for fourth format conversion character
686 * @param(a5) value for fifth format conversion character
687 * @param(a6) value for sixth format conversion character
688 *
689 * @a(Examples)
690 * The following example demonstrates a typical usage.
691 * @p(code)
692 * String list[];
693 * UInt i;
694 *
695 * Log_print2(Diags_USER2, "list[%u] = %s\n", i, (IArg)list[i]);
696 * @p
697 * Note that the `IArg` cast above is only necessary for pointer
698 * arguments; C's normal parameter conversions implicitly convert
699 * integral arguments.
700 *
701 * To simplify the conversion from `float` arguments to `IArg`,
702 * the standard header `xdc/std.h` provides a macro, named floatToArg(),
703 * to do this conversion in a type safe manner. So, the following
704 * statement will print "`float = 2.3456`":
705 * @p(code)
706 * Log_print1(Diags_USER1, "float = %f", floatToArg(2.34567));
707 * @p
708 *
709 * Note that, if you are formatting events on the target, you must
710 * also add support for floating point to ASCII conversion to
711 * `{@link System#printf}`; for more information, see the
712 * `{@link System#extendedFormats}` reference documenation. For example:
713 * @p(code)
714 * var System = xdc.useModule('xdc.runtime.System');
715 * System.extendedFormats = "%f";
716 * @p
717 */
718 @Macro Void print6(Diags.Mask mask, CString fmt, IArg a1, IArg a2,
719 IArg a3, IArg a4, IArg a5, IArg a6);
720
721 /*!
722 * ======== error0 ========
723 * Generate a `Log` "error event" with 0 arguments
724 *
725 * @see #error5
726 */
727 @Macro Void error0(CString fmt);
728
729 /*!
730 * ======== error1 ========
731 * Generate a `Log` "error event" with 1 argument
732 *
733 * @see #error5
734 */
735 @Macro Void error1(CString fmt, IArg a1);
736
737 /*!
738 * ======== error2 ========
739 * Generate a `Log` "error event" with 2 arguments
740 *
741 * @see #error5
742 */
743 @Macro Void error2(CString fmt, IArg a1, IArg a2);
744
745 /*!
746 * ======== error3 ========
747 * Generate a `Log` "error event" with 3 arguments
748 *
749 * @see #error5
750 */
751 @Macro Void error3(CString fmt, IArg a1, IArg a2, IArg a3);
752
753 /*!
754 * ======== error4 ========
755 * Generate a `Log` "error event" with 4 arguments
756 *
757 * @see #error5
758 */
759 @Macro Void error4(CString fmt, IArg a1, IArg a2, IArg a3,
760 IArg a4);
761
762 /*!
763 * ======== error5 ========
764 * Generate a `Log` "error event" with 5 arguments
765 *
766 * The Log_error APIs are intended to allow users to easily log error
767 * events in their code. Similar to the Log_print APIs, Log_error does not
768 * require that you define an event. You simply pass an informative error
769 * string which can optionally be formatted with additional arguments. The
770 * error is logged with the predefined event {@link #L_error}.
771 *
772 * Log_error prepends a string to the message which identifies it as an
773 * ERROR and specifies the filename and line number of the Log_error call
774 * site. A simple example:
775 *
776 * @p(code)
777 * Log_error0("Invalid argument");
778 * @p
779 * This event will be formatted as (assuming that the above call was line
780 * 35 of "MyCode.c")
781 * @p(code)
782 * ERROR at "MyCode.c", line 35: Invalid argument
783 * @p
784 *
785 * Users may provide additional information in the error event, such as
786 * a predefined error code or details of the error. These additional
787 * values will be used to format the string passed to Log_error.
788 * @see #print6 for information about format strings.
789 *
790 * Log_error does not use a variable length argument list--you must call
791 * the appropriate Log_errorX API based on the number of arguments.
792 *
793 * @param(fmt) a reference to a constant error string / fmt string
794 * @param(a1) value for an additional parameter (e.g. an error code)
795 * @param(a2) value for an additional parameter
796 * @param(a3) value for an additional parameter
797 * @param(a4) value for an additional parameter
798 * @param(a5) value for an additional parameter
799 *
800 * @a(Examples)
801 * The following example demonstrates a typical usage.
802 * @p(code)
803 * Int myArg;
804 *
805 * Log_error1("Invalid argument: %d", myArg);
806 * @p
807 * The above event is formatted as, for example:
808 * @p(code)
809 * ERROR: "MyCode.c", line 35: Invalid argument: -1
810 * @p
811 */
812 @Macro Void error5(CString fmt, IArg a1, IArg a2, IArg a3,
813 IArg a4, IArg a5);
814
815 /*!
816 * ======== warning0 ========
817 * Generate a `Log` "warning event" with 0 arguments
818 *
819 * @see #warning5
820 */
821 @Macro Void warning0(CString fmt);
822
823 /*!
824 * ======== warning1 ========
825 * Generate a `Log` "warning event" with 1 argument
826 *
827 * @see #warning5
828 */
829 @Macro Void warning1(CString fmt, IArg a1);
830
831 /*!
832 * ======== warning2 ========
833 * Generate a `Log` "warning event" with 2 arguments
834 *
835 * @see #warning5
836 */
837 @Macro Void warning2(CString fmt, IArg a1, IArg a2);
838
839 /*!
840 * ======== warning3 ========
841 * Generate a `Log` "warning event" with 3 arguments
842 *
843 * @see #warning5
844 */
845 @Macro Void warning3(CString fmt, IArg a1, IArg a2, IArg a3);
846
847 /*!
848 * ======== warning4 ========
849 * Generate a `Log` "warning event" with 4 arguments
850 *
851 * @see #warning5
852 */
853 @Macro Void warning4(CString fmt, IArg a1, IArg a2, IArg a3,
854 IArg a4);
855
856 /*!
857 * ======== warning5 ========
858 * Generate a `Log` "warning event" with 5 arguments
859 *
860 * The Log_warning APIs provide the same features as the Log_error APIs,
861 * but are used to specifically log "warning" events.
862 * @see #error5
863 *
864 * The Log_warning APIs are equivalent to the Log_error APIs except that
865 * they use the predefined {@link #L_warning} event. Log_warning prepends
866 * a string to the message which identifies it as a WARNING and specifies
867 * the filename and line number of the Log_warning call site.
868 *
869 * @param(fmt) reference to a constant warning string / fmt string
870 * @param(a1) value for an additional parameter (e.g. a warning code)
871 * @param(a2) value for an additional parameter
872 * @param(a3) value for an additional parameter
873 * @param(a4) value for an additional parameter
874 * @param(a5) value for an additional parameter
875 *
876 * @a(Examples)
877 * The following example demonstrates a typical usage.
878 * @p(code)
879 * Int myArg;
880 *
881 * Log_warning1("Value may be too high: %d", myArg);
882 * @p
883 * The above event is formatted as:
884 * @p(code)
885 * WARNING: "MyCode.c", line 50: Value may be too high: 4096
886 * @p
887 */
888 @Macro Void warning5(CString fmt, IArg a1, IArg a2, IArg a3,
889 IArg a4, IArg a5);
890
891 /*!
892 * ======== info0 ========
893 * Generate a `Log` "info event" with 0 arguments
894 *
895 * @see #info5
896 */
897 @Macro Void info0(CString fmt);
898
899 /*!
900 * ======== info1 ========
901 * Generate a `Log` "info event" with 1 argument
902 *
903 * @see #info5
904 */
905 @Macro Void info1(CString fmt, IArg a1);
906
907 /*!
908 * ======== info2 ========
909 * Generate a `Log` "info event" with 2 arguments
910 *
911 * @see #info5
912 */
913 @Macro Void info2(CString fmt, IArg a1, IArg a2);
914
915 /*!
916 * ======== info3 ========
917 * Generate a `Log` "info event" with 3 arguments
918 *
919 * @see #info5
920 */
921 @Macro Void info3(CString fmt, IArg a1, IArg a2, IArg a3);
922
923 /*!
924 * ======== info4 ========
925 * Generate a `Log` "info event" with 4 arguments
926 *
927 * @see #info5
928 */
929 @Macro Void info4(CString fmt, IArg a1, IArg a2, IArg a3, IArg a4);
930
931 /*!
932 * ======== info5 ========
933 * Generate a `Log` "info event" with 5 arguments
934 *
935 * The Log_info APIs are provided for easily logging generic
936 * "informational" events with call site information. They are similar to
937 * the Log_print APIs in that they do not require you to define an event--
938 * you simply pass an informative printf-style string which can optionally
939 * be formatted with additional arguments. The info record is logged with
940 * the predefined event '{@link #L_info}'.
941 *
942 * The Log_info APIs log the {@link #L_info} event which uses the 'INFO'
943 * diags category. They do not allow you to specify an event priority.
944 *
945 * Log_info prepends the filename and line number of the call site to the
946 * message.
947 *
948 * @param(fmt) reference to a constant event string / fmt string
949 * @param(a1) value for an additional parameter (e.g. an event code)
950 * @param(a2) value for an additional parameter
951 * @param(a3) value for an additional parameter
952 * @param(a4) value for an additional parameter
953 * @param(a5) value for an additional parameter
954 *
955 * @a(Examples)
956 * The following example demonstrates a typical usage.
957 * @p(code)
958 * Int load;
959 *
960 * Log_info1("Current load: %d", load);
961 * @p
962 * The above event is formatted as, for example:
963 * @p(code)
964 * "MyCode.c", line 15: Current load: 25
965 * @p
966 */
967 @Macro Void info5(CString fmt, IArg a1, IArg a2, IArg a3, IArg a4,
968 IArg a5);
969
970 /*!
971 * ======== put0 ========
972 * Unconditionally put the specified Log event with 0 arguments
973 *
974 * @see #put8
975 */
976 @Macro Void put0(Log.Event evt, Types.ModuleId mid);
977
978 /*!
979 * ======== put1 ========
980 * Unconditionally put the specified Log event and 1 argument
981 *
982 * @see #put8
983 */
984 @Macro Void put1(Log.Event evt, Types.ModuleId mid, IArg a1);
985
986 /*!
987 * ======== put2 ========
988 * Unconditionally put the specified Log event and 2 arguments
989 *
990 * @see #put8
991 */
992 @Macro Void put2(Log.Event evt, Types.ModuleId mid, IArg a1, IArg a2);
993
994 /*!
995 * ======== put4 ========
996 * Unconditionally put the specified Log event and 4 arguments
997 *
998 * @see #put8
999 */
1000 @Macro Void put4(Log.Event evt, Types.ModuleId mid, IArg a1, IArg a2,
1001 IArg a3, IArg a4);
1002
1003 /*!
1004 * ======== put8 ========
1005 * Unconditionally put the specified Log event and 8 arguments
1006 *
1007 * This method unconditionally puts the specified `{@link Event}`
1008 * `evt` into the log. The `{@link Types#ModuleId}` `mid` should be the
1009 * module ID of the module which is putting the event.
1010 *
1011 * @param(evt) the Log event to put into the log
1012 * @param(mid) module ID of the module putting the event
1013 * @param(a1) value for first format conversion character
1014 * @param(a2) value for second format conversion character
1015 * @param(a3) value for third format conversion character
1016 * @param(a4) value for fourth format conversion character
1017 * @param(a5) value for fifth format conversion character
1018 * @param(a6) value for sixth format conversion character
1019 * @param(a7) value for seventh format conversion character
1020 * @param(a8) value for eighth format conversion character
1021 */
1022 @Macro Void put8(Log.Event evt, Types.ModuleId mid, IArg a1, IArg a2,
1023 IArg a3, IArg a4, IArg a5, IArg a6, IArg a7, IArg a8);
1024
1025 /*!
1026 * ======== write0 ========
1027 * Generate a `Log` event with 0 arguments
1028 *
1029 * @see #write8
1030 */
1031 @Macro Void write0(Event evt);
1032
1033 /*!
1034 * ======== write1 ========
1035 * Generate a `Log` event with 1 argument
1036 *
1037 * @see #write8
1038 */
1039 @Macro Void write1(Event evt, IArg a1);
1040
1041 /*!
1042 * ======== write2 ========
1043 * Generate a `Log` event with 2 arguments
1044 *
1045 * @see #write8
1046 */
1047 @Macro Void write2(Event evt, IArg a1, IArg a2);
1048
1049 /*!
1050 * ======== write3 ========
1051 * Generate a `Log` event with 3 arguments
1052 *
1053 * @see #write8
1054 */
1055 @Macro Void write3(Event evt, IArg a1, IArg a2, IArg a3);
1056
1057 /*!
1058 * ======== write4 ========
1059 * Generate a `Log` event with 4 arguments
1060 *
1061 * @see #write8
1062 */
1063 @Macro Void write4(Event evt, IArg a1, IArg a2, IArg a3, IArg a4);
1064
1065 /*!
1066 * ======== write5 ========
1067 * Generate a `Log` event with 5 arguments
1068 *
1069 * @see #write8
1070 */
1071 @Macro Void write5(Event evt, IArg a1, IArg a2, IArg a3, IArg a4, IArg a5);
1072
1073 /*!
1074 * ======== write6 ========
1075 * Generate a `Log` event with 6 arguments
1076 *
1077 * @see #write8
1078 */
1079 @Macro Void write6(Event evt, IArg a1, IArg a2, IArg a3, IArg a4,
1080 IArg a5, IArg a6);
1081
1082 /*!
1083 * ======== write7 ========
1084 * Generate a `Log` event with 7 arguments
1085 *
1086 * @see #write8
1087 */
1088 @Macro Void write7(Event evt, IArg a1, IArg a2, IArg a3, IArg a4,
1089 IArg a5, IArg a6, IArg a7);
1090
1091 /*!
1092 * ======== write8 ========
1093 * Generate a `Log` event with 8 arguments
1094 *
1095 * If the mask in the specified `Log` event has any bit set which is
1096 * also set in the current module's diagnostics mask, then this call to
1097 * write will "raise" the given `Log` event.
1098 *
1099 * @param(evt) the `Log` event to write
1100 * @param(a1) value for first format conversion character
1101 * @param(a2) value for second format conversion character
1102 * @param(a3) value for third format conversion character
1103 * @param(a4) value for fourth format conversion character
1104 * @param(a5) value for fifth format conversion character
1105 * @param(a6) value for sixth format conversion character
1106 * @param(a7) value for seventh format conversion character
1107 * @param(a8) value for eighth format conversion character
1108 */
1109 @Macro Void write8(Event evt, IArg a1, IArg a2, IArg a3, IArg a4,
1110 IArg a5, IArg a6, IArg a7, IArg a8);
1111
1112 /*!
1113 * ======== doPrint ========
1114 * Render an event as text via `{@link System#printf System_printf}`
1115 *
1116 * This method is not gated and may make more than one call to
1117 * `System_printf`. This utility method is typically used within the
1118 * implementation of a logger which initializes
1119 * `{@link #EventRec Log_EventRec}` structures based on `Log` events
1120 * produced by the application.
1121 *
1122 * @param(evRec) a non`NULL` pointer to an initialized `Log_EventRec`
1123 * structure to be formated via
1124 * `{@link System#printf System_printf}`.
1125 */
1126 Void doPrint(EventRec *evRec);
1127
1128 /*!
1129 * @_nodoc
1130 * ======== lookupEventMessage ========
1131 * Returns the format string for the event with the given id.
1132 */
1133 function lookupEventMessage(eventId);
1134
1135 /*!
1136 * @_nodoc
1137 * ======== getTargetArgSize ========
1138 * Returns the target size of a record argument in bytes (not MAUs).
1139 */
1140 function getTargetArgSize();
1141
1142 /*!
1143 * @_nodoc
1144 * ======== lookupEventName ========
1145 */
1146 function lookupEventName(eventId);
1147
1148 /*!
1149 * @_nodoc
1150 * ======== lookupModuleName ========
1151 */
1152 function lookupModuleName(modId);
1153
1154 /*!
1155 * @_nodoc
1156 * ======== getTargetEventRecSize ========
1157 * Returns the record size in bytes (not MAUs).
1158 */
1159 function getTargetEventRecSize();
1160
1161 internal:
1162
1163 1164 1165 1166
1167 metaonly config String idToInfo[string] = [];
1168 }
1169 1170 1171
1172


Abraham is a graduate of the University of Notre Dame, where he majored in Computer Science. He is an experienced consultant at Protiviti with a focus on technology and innovation. He has experience with the latest technologies including AWS, DevOps tools, Software Development and Automation. He is an advocate of continous education and passionate about learning about the latest and greatest technological advances.
Working with Protiviti’s DevSecOps team, scripted a CI/CD pipeline utilizing Jenkins and Infrastructure as Code tools such as Terraform and Packer to automate the deployment of multiple open source security and code quality tools such as SonarQube, Dependency Track, Hashicorp Vault, CyberArk Conjur and more onto an AWS infrastructure. Project allows startups or young companies to quickly and securely establish a scalable DevOps CI/CD program in AWS within minutes that is tailored to their security needs and budget.
Worked with Professor Aaron Striegel to come up with a way to see if an individual has shot a firegun by using the technologies in wearables and smartphones.
Assisted the Office of Student Affairs with everyday tasks. Helped to plan and direct events for the University of Notre Dame.
Led and organized events for undergraduate residents living on campus. Facilitated first year students’ transition from secondary school to university both socially and academically.
Gained experience managing customer database, building a customer network and scraping the web for useful data.
GPA: 3.13
GPA: 4.57
Throughout my years at Notre Dame, I've had the privilege to participate in many Engineering and Computer Science Projects, both in teams and individually. Here are a few of them:
I worked under Professor Aaron Striegel to research whether we could use current technology in smartphones and wearables to accurately tell if a firearm has gone off. This could be used as an alternative to GSR (gunshot residue) or acoustic measures to see if a firearm has been shot. I learned to use Xcode and code in Swift in order to code and iOS and watchOS app for my iPhone and Apple Watch. This app would collect the data of the accelerometer and gyroscope of the devices, turn it into a csv file and have the ability to export this file. From here, I was able to manipulate this data using several python scripts. These scripts would plot the data received an allow me to isolate events from this data. Once we have the data from a desired event, we can use machine learning in order to see what gunfire looks like based on the acceleration in three dimensions. All data was recorded at 50hz. If you want more information on this project, please feel free to email me.
As a team, we created a file monitoring application called rorschach, which scans a root directory for any changes to files underneath this folder and executes user-specified actions on the files based on pattern matching rules. We did this in C++ by using several data structures to keep track of the modification times, actions being performed on a file etc. Through this project, we were introduced to signals, environmental variables and to the structure of a file system.
As a team, we built a multi-core process queue, whose purpose is to receive a series of jobs and then schedule them to run on multiple CPU cores as separate processes. This project introduced us to client server protocols and communications as well as the use of scheduling for jobs (FIFO, Round Robin, Multi-Level Feedback Queue). For this project, we decided to use unix domain sockets as they enable two way communication between our client and server. The entire client and server were coded in C++. Once it was all coded, we benchmarked each of the different scheduling policies to see which ones performed better with different types of tasks. This was one of the more code intensive project that I've been a part of.
In this group project, we created an event driven publish subscribe library later to be used in a real time messaging application. This was all created in C++. The first target was to create a library that utilizes POSIX threads and concurrent data structures to implement a client. The server was provided to us. After the API was done, we implemented a simple messaging app using this API. It consisted of a client subscribing to a TOPIC, which would be the groupchat name, and sending and recieving messages back and forth to other clients subscribed to this TOPIC.
Built and implementation of the language C commands malloc and free, which allocate and free memory from the heap. To do this, we learned how memory management is handled by the OS. We learned about splitting and coalescing blcoks, implementation of heap management strategies including Next Fit, Best Fit and Worst Fit. Once these strategies had been implemented, we benchmarked the different startegies by creating different scripts in Python. We learned which strategies worked best for reusing free blocks, requiring the least amount of space, allowing for the most splits and so on.
Coded a simplified implementation of memcached which is in-memory key-value store that is used for quick access to frequently used computations (cache). In teams of 3, we used a C++ thread library to create a cache that supports concurrent access. We learned about the possible threats of concurrency and how to get around them using solutions such as semaphores and locks. Further, we learned about Page Tables and how they work. We implemented four eviction policies including FIFO, Random, LRU, and Clock for Page Entries.
In this team project, we created a version of the Unix File System. We furthered learned about Blocks, SuperBlocks, Inodes etc. We learned how a file system handles signals and the structure of a Simple FS.
One of my biggest passions through my childhood was content creation, more specifically video and 3d modeling. During my junior year, I got to mess around with 3D animations using the MAYA 2018 software. These were a few of my creations:


My first Header1
My first Header2
My first
paragraph
Email your
grandma
I can make bold text
I can also make italicized text
My name is
Zac Schulwolf


Research Projects
We aim to build algorithms for perceptual representations learned by and for interaction, causal understanding of mechanisms, and physically-grounded reasoning in practical settings. An emblematic north star is to enable an autonomous robot to watch an instructional video, or a set of these videos, and then learn a policy to execute the task in a new setting. We build both algorithms and systems that have a broad range of applications in different domains in robot autonomy. PAIR group blends ideas in Causality, Perception, and Reinforcement Learning towards this vision.
1. Generalizable Representations in RL for Robotics
A key focus of our work is to understand the role of representations in RL towards efficiency and generalization in skill acquisition. RL is mainly composed of State Space (Input), Action space (Output), a Learning Rule, and Policy (or value) model.
Structured biases upend contemporary methods in all four dimensions, pointing to a need for deeper analysis of representations in RL.
States: Task Oriented Grasping, Affordance for Tool-Use, Making Sense of Touch and Vision
Actions: VICES, LASER
Algorithms: C-Learning
Architectures: Deep-Dense nets in RL
- 3D Vision: Object and Scene representations for manipulation.
- Perceptual Concept Learning
- Geomteric Deep Learning for discovery of symmetries
2. Causal Discovery and Inference in Robotics
Causal understanding is one of key pillars of my current and future agenda. A simulator is a generative world model, and similarly follows a system of structural mechanisms. However, model learning focuses solely on statistical dependence, while Causal Models go beyond it to build representations that support intervention, planning, and modular reasoning. These methods provide a concrete step towards bridging vision and robotics through sub-goal inference and counterfactual imagination.
- Disentangled Generative Models: Semi-Supervised StyleGAN, Unsupervised Keypoints
- Causal Factor Graphs: Visual Causal Discovery
- Instruction Guided Counterfactual Generation: Action Concepts
3. Crowd-Scale Robot Learning with Offline/Batch RL
Data-driven methods help RL in exploration and reward specification. Robot learning, however, is limited by modest-sized real data. Access to data brings new algorithmic opportunities to robotics, as it did in vision and language. However, it also poses challenges due to static nature of data and covariate shifts.
- Scalable Teleoperation with Roboturk: Roboturk-v1, Roboturk-v2
- Offline/Batch Policy Learning and Causal Data Augmengation: IRIS, CoDA
- Safe Transfer to Real Systems: Adversarial Policy Learning, Adaptive Polict Transfer, Conservative Safety Critics
4. Structured Biases for Hierarchical Planning
Procedural reasoning, such as in robotics, needs both skills and their structured composition for interaction planning towards a higher-order objective. However, manual composition of skills via a finite state-machine design is both tedious and unscalable. Thus the need for inductive bias is intensified for cognitive reasoning. I have developed imitation guided policy learning in abstract spaces for hierarchically structure tasks.
- Neural Planning Modules for One-Shot Imitation: NTP, NTG, Continuous Symbolic Planner
- Task Structure Representations: Transition State Clustering, TSC-DL, SWIRL
- Learning from Videos: Finding-it
- Dynamics with Latent Hierarchical Structure: CAVIN
5. Applications to Real Robot Systems
The algorithmic ideas have been motivated by problems in mobility and manipulation in robotics, and have been evaluated on various physical robot platforms.
- Personal & Service Robotics: Tool Use, Task Planning, Assembly, Pick & place, Laundry Layout
- Surgical & Healthcare: Debridement, Suturing, Cutting, Extraction, Radiotherapy
- Legged Robotics: Contact Planning, Domain Randomization


Enter DARTH VADER, carrying REBEL LEADER 1 by the neck, and STORMTROOPERS.
REBEL 1:
The Death Star plans we could not find herein,
Nor are they on the main computer, Lord.
In short, they are not here, and there's an end.
VADER:
Thou speakest well, my stormtrooper, and yet
Not well upon my ear the message falls.
I turn to thee thou rebel. Aye, I lift
Thy head above my own. Thou canst now choose
To keep thy secretes lock'd safe in head,
And therefore lose the life thou holdest dear,
Or else to keep thy head and, thus, thy life.
My paitence runneth quickly out much like
The sands across the dunes of Tatooine.
So tell me, else thou diest quick: where shall
We find transmission thou didst intercept?
What hast thou done, say, with those plans?
REBEL 1:
- My Lord,
My head and life I value - Certain 'tis!
And yet to thee I must report we have
Not intercepted one transmission! Ahh!
This is a cons'lar ship, nothing more,
On dipomatic mission. Ugh!
VADER:
-Thou knave!
 Commander,
prithee, go!

[Exeunt stormtroopers.]
And so another dies by my own hand,
This hand, which now encas'd in blackness is.
O that the fingers of this wretched hand
Had not the pain of suff'ring ever known.
But now my path is join'd unto the dark,
And wicked men - whose hands and fingers move
To crush their foes - are now my company.
So shall my fingers ever undertake
To do more evil, aye, and this- my hand-
Shall do the Emp'ror's bidding evermore.
And thus we see how fingers presage death
And hands become the insturments of Fate.
Enter STORMTROOPERS, searchin. Enter PRINCESS LEIA, holding a blaster.
TROOPER 1:
Aye, there is one. My comrades, set for stun!
TROOPER 2:
She shall be well. Go now, inform the dread
Lord Vader we have caught a prisoner.
[Aside:] And may Mos Eisley drinks flow swift and
free
When Vadar grants rewords for work well done!


{{+bindTo:partials.standard_nacl_api}}
| AudioEncoder () | |
| AudioEncoder (const InstanceHandle &instance) | |
| AudioEncoder (const AudioEncoder &other) | |
| int32_t | GetSupportedProfiles (const CompletionCallbackWithOutput< std::vector< PP_AudioProfileDescription > > &cc) |
| int32_t | Initialize (uint32_t channels, PP_AudioBuffer_SampleRate input_sample_rate, PP_AudioBuffer_SampleSize input_sample_size, PP_AudioProfile output_profile, uint32_t initial_bitrate, PP_HardwareAcceleration acceleration, const CompletionCallback &cc) |
| int32_t | GetNumberOfSamples () |
| int32_t | GetBuffer (const CompletionCallbackWithOutput< AudioBuffer > &cc) |
| int32_t | Encode (const AudioBuffer &buffer, const CompletionCallback &cc) |
| int32_t | GetBitstreamBuffer (const CompletionCallbackWithOutput< PP_AudioBitstreamBuffer > &cc) |
| void | RecycleBitstreamBuffer (const PP_AudioBitstreamBuffer &bitstream_buffer) |
| void | RequestBitrateChange (uint32_t bitrate) |
| void | Close () |
Audio encoder interface.
Typical usage:
PPB_MediaStreamAudioTrack
.Available audio codecs vary by platform. All: opus.
Default constructor for creating an is_null() AudioEncoder
object.
| pp::AudioEncoder::AudioEncoder | ( | const InstanceHandle & | instance | ) | [explicit] |
A constructor used to create a AudioEncoder
and associate it with the provided Instance
.
| [in] | instance | The instance with which this resource will be associated. |
| pp::AudioEncoder::AudioEncoder | ( | const AudioEncoder & | other | ) |
The copy constructor for AudioEncoder
.
| [in] | other | A reference to a AudioEncoder . |
| void pp::AudioEncoder::Close | ( | ) |
Closes the audio encoder, and cancels any pending encodes.
Any pending callbacks will still run, reporting PP_ERROR_ABORTED
. It is not valid to call any encoder functions after a call to this method. Note: Destroying the audio encoder closes it implicitly, so you are not required to call Close().
| int32_t pp::AudioEncoder::Encode | ( | const AudioBuffer & | buffer, |
| const CompletionCallback & | cc | ||
| ) |
Encodes an audio buffer.
| [in] | audio_buffer | The AudioBuffer to be encoded. |
| [in] | callback | A CompletionCallback to be called upon completion. Plugins that pass AudioBuffer resources owned by other resources should wait for completion before reusing them. |
pp_errors.h
. Returns PP_ERROR_FAILED if Initialize() has not successfully completed. | int32_t pp::AudioEncoder::GetBitstreamBuffer | ( | const CompletionCallbackWithOutput< PP_AudioBitstreamBuffer > & | cc | ) |
Gets the next encoded bitstream buffer from the encoder.
| [in] | callback | A CompletionCallbackWithOutput to be called upon completion with the next bitstream buffer. The plugin can call GetBitstreamBuffer from the callback in order to continuously "pull" bitstream buffers from the encoder. |
pp_errors.h
. Returns PP_ERROR_FAILED if Initialize() has not successfully completed. Returns PP_ERROR_INPROGRESS if a prior call to GetBitstreamBuffer() has not completed. | int32_t pp::AudioEncoder::GetBuffer | ( | const CompletionCallbackWithOutput< AudioBuffer > & | cc | ) |
Gets a blank audio frame which can be filled with audio data and passed to the encoder.
| [in] | callback | A CompletionCallbackWithOutput to be called upon completion with the blank AudioBuffer resource. |
pp_errors.h
. | int32_t pp::AudioEncoder::GetNumberOfSamples | ( | ) |
Gets the number of audio samples per channel that audio buffers must contain in order to be processed by the encoder.
This will be the number of samples per channels contained in buffers returned by GetBuffer().
pp_errors.h
. Returns PP_ERROR_FAILED if Initialize() has not successfully completed. | int32_t pp::AudioEncoder::GetSupportedProfiles | ( | const CompletionCallbackWithOutput< std::vector< PP_AudioProfileDescription > > & | cc | ) |
Gets an array of supported audio encoder profiles.
These can be used to choose a profile before calling Initialize().
| [in] | callback | A CompletionCallbackWithOutput to be called upon completion with the PP_AudioProfileDescription structs. |
pp_errors.h
. | int32_t pp::AudioEncoder::Initialize | ( | uint32_t | channels, |
| PP_AudioBuffer_SampleRate | input_sample_rate, | ||
| PP_AudioBuffer_SampleSize | input_sample_size, | ||
| PP_AudioProfile | output_profile, | ||
| uint32_t | initial_bitrate, | ||
| PP_HardwareAcceleration | acceleration, | ||
| const CompletionCallback & | cc | ||
| ) |
Initializes a audio encoder resource.
This should be called after GetSupportedProfiles() and before any functions below.
| [in] | channels | The number of audio channels to encode. |
| [in] | input_sampling_rate | The sampling rate of the input audio buffer. |
| [in] | input_sample_size | The sample size of the input audio buffer. |
| [in] | output_profile | A PP_AudioProfile specifying the codec profile of the encoded output stream. |
| [in] | initial_bitrate | The initial bitrate for the encoder. |
| [in] | acceleration | A PP_HardwareAcceleration specifying whether to use a hardware accelerated or a software implementation. |
| [in] | callback | A CompletionCallback to be called upon completion. |
pp_errors.h
. Returns PP_ERROR_NOTSUPPORTED if audio encoding is not available, or the requested codec profile is not supported. Returns PP_ERROR_NOMEMORY if bitstream buffers can't be created. | void pp::AudioEncoder::RecycleBitstreamBuffer | ( | const PP_AudioBitstreamBuffer & | bitstream_buffer | ) |
Recycles a bitstream buffer back to the encoder.
| [in] | bitstream_buffer | APP_AudioBitstreamBuffer that is no longer needed by the plugin. |
| void pp::AudioEncoder::RequestBitrateChange | ( | uint32_t | bitrate | ) |
Requests a change to the encoding bitrate.
This is only a request, fulfilled on a best-effort basis.
| [in] | audio_encoder | A PP_Resource identifying the audio encoder. |


Design
Make your website look beautifully, with simple and stunning design.
Learn More
Develop
Up to date with the latest modern tools for today's demanding task.
Learn More
Deploy
Aesthetics and functionality working seamlessly, it's the magic behind the art.
Learn More