class: center, middle, inverse, title-slide # ETC1010: Advanced Modeling ## Distributions, Inference, Diagnostics, Decision trees ### Di Cook (
<EMAIL_ADDRESS>,
@visnut
) ### 3/10/2017 --- # Outline - Linear model diagnostics - Regression trees, model by optimisation - Fit all possible models - Using linear models for exploration --- # Linear model diagnostics - Response variable, `\(y\)` - Predictors, or explanatory variables, `\(x_1, \dots, x_p\)` - Assumptions, residual diagnostics - `\(R^2\)`, deviance, AIC, BIC, likelihood - Statistically significant, and variable selection --- # Multiple regression model `$$y_i=\beta_0+\beta_1x_{i1}+\dots +\beta_px_{ip}+\varepsilon_i, ~~~ i=1, \dots, n$$` where `\(\varepsilon\)` is a sample from a normal distribution, `\(N(0, \sigma^2)\)`. By optimisation, of `\(\sum_i (y_i-(b_0+b_1x_{i1}+\dots +b_px_{ip}))^2\)`, we found the line of best fit, and parameter estimates `\((b_0, b_1, \dots, b_p, \hat{\sigma})\)` for the "true" (population) model. For a simple linear model, `$$b_1 = r \frac{s_y}{s_y}$$` is the *slope* `$$b_0 = \bar{y} - b_1 \bar{x}$$` is the *intercept*, and `$$\hat{\sigma}^2 = \frac{1}{n}\sum_{i=1}^{n} (y_i - (b_0+b_1x_{i1}+\dots +b_px_{ip}))^2$$` is also called the *mean squared error*. --- # Population vs sample Often the data we have is a sample from all possible values available in a larger population. Using the sample we would like to be able to say something about the patterns in the entire population. |Population| <-> |Sample| |:---:|:---:|:---:| |parameters| |statistics| | `\(\beta_k\)` | | `\(b_k\)` | | `\(\sigma\)` | | `\(s\)` | | `\(\mu\)` | | `\(\bar{x}\)` | The population parameters are unknown. The statistics are calculated from the sample, so are known. The model should be written this way: `$$\hat{y} = b_0+b_1x_{1}+\dots +b_px_{p}$$` Note the fitted model, and fitted values, are called *y hat* . The fitted values are points along the line. --- # Normal residuals The assumption is that `\(\varepsilon \sim N(0, \sigma^2)\)` implies that `$$y|x_1, \dots, x_p \sim N(b_0+b_1x_{1}+\dots +b_px_{p}, \sigma^2)$$`  Regardless of the value of `\(x\)` the distribution of points above and below the line should be the same, and symmetric. And as you get further form the line, there should be less points. --- # Implications - Optimisation function should consider the distribution assumption - Need to check the residuals from the model fit satisfy the normality assumption. --- # Optimisation Normal density function `$$f(x) = \frac{1}{\sqrt{2\pi}} \exp \left\{ -\frac{1}{2} \left(\frac{x-\mu}{\sigma}\right)^2 \right\}$$` For error, `\(\mu=0\)`. The likelihood function is the product of the density function evaluated for each sample value, `\(x_1, ..., x_n\)`. `$$l(\mu, \sigma|x_1, \dots, x_n) = \frac{1}{\sqrt{2\pi}} \exp \left\{ -\frac{1}{2} \left(\frac{x_1-\mu}{\sigma}\right)^2 \right\}\times ... \times \frac{1}{\sqrt{2\pi}} \exp \left\{ -\frac{1}{2} \left(\frac{x_n-\mu}{\sigma}\right)^2 \right\}$$` E.g. suppose `\(x_1 = 1, x_2 = -3\)`, then the likelihood is, assuming `\(\mu=0\)`, `$$l(\sigma|x_1=1, x_2=-3) = \frac{1}{2\pi}\exp\left\{-\frac{1}{2}\frac{(1+9)}{\sigma^2}\right\}$$` which is a function in `\(\sigma\)`. Optimise this function to get the maximum likelihood estimate for `\(\sigma\)`. --- # Intercept and slope Set `\(\mu=\beta_0+\dots+\beta_1x\)` and then the likelihood is a function of `\(\sigma, \beta_0, \dots, \beta_p\)`. Optimise the function over all of these parameters to get the maximum likelihood estimates for the linear model. These will be the same as if you minimised the least squares equation, `\(\sum_i (y_i-(b_0+b_1x_{1}+\dots +b_px_{p}))^2\)`. --- # Checking normality - Plot residuals vs fitted: is it nice and uniform? - Make a histogram: is it symmetric, unimodal, no outliers? - Make a normal probability plot: does it pass the fat marker test?  --- # Common problems - Non-linear relationship - Heteroskedastic error - Outliers  --- Its good to overlay a smoother sometimes.  --- # Model fit - `\(R^2\)`: proportion of variation explained by model - deviance, null deviance - AIC, BIC, negative loglikelihood --- # Proportion of variation explained `$$R^2 = 1 - \frac{SSE}{SST}$$` where `\(SST = \sum_i (y_i-\bar{y})^2\)` and `\(SSE = \sum_i (y_i-\hat{y})^2\)`. `\(0 < R^2 < 1\)`, where `\(1\)` would indicate the model explains ALL the variation in `\(y\)`, and `\(0\)` indicates it explains nothing.  --- # Deviance and null deviance - Most software does not report `\(R^2\)` any more - Related to the distributional assumptions on the error - *deviance* : up to a constant, minus twice the maximized log-likelihood. - *null deviance* : The deviance for the null model, comparable with deviance. - A good model has a deviance that is much smaller than the null deviance, which means that it explains a lot of the variability in `\(y\)`. (Or the closer to `\(0\)` the better.) - Deviance will decrease as more variables added to the model. --- # AIC, BIC - AIC (Akaike Information Criterion): minus twice the maximized log-likelihood plus twice the number of parameters - The lower the value the better the model - Primarily used to compare models, pick the model with the lowest value - BIC (Bayes Information Criterion) small variation, instead of twice, use `log(n)`, the number of parameters. --- # Model building - Statistical tests can be used to determine whether parameter estimates indicate the true parameter is different from zero - Use AIC to help select variables when there are many --- # Statistical tests on parameters .left-column[  ] .right-column[ ``` Call: glm(formula = y ~ x, data = df) Deviance Residuals: Min 1Q Median 3Q Max -1.11603 -0.31440 -0.06325 0.36795 1.18757 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 15.02681 0.08495 176.89 <2e-16 *** x -2.02429 0.15554 -13.02 <2e-16 *** --- Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 (Dispersion parameter for gaussian family taken to be 0.225614) Null deviance: 60.324 on 99 degrees of freedom Residual deviance: 22.110 on 98 degrees of freedom AIC: 138.87 Number of Fisher Scoring iterations: 2 ``` ] --- # Statistical tests on parameters - `t value` is calculated by `Estimate` divided by `Std. Error` - If `t value` is large, indicates that the `\(\beta_k\)` (population parameter) is unlikely to be `\(0\)`. Given what we have seen in the sample, it indicates that this parameter, and thus the variable associated with it is important (statistically significant) for explaining `\(y\)`. - This should correspond to a `Pr(>|t|)` (*p-value*) being really small, less than 0.1. - Both `\(\beta_0\)` and `\(\beta_1\)` in the example here are statistically significant (both different from `\(0\)`) and so `\(x_1\)` is really important for explaining `\(y\)`. --- # Interpretation - Intercept: When `\(x_1=0\)`, then estimated `\(y\)` is `\(b_0\)`. Often doesn't make sense, but its important for the math to have this as part of the model - Slope: For each unit increase in `\(x_1\)`, `\(y\)` increases, on average, by `\(b_1\)`. - For multiple predictors, the interpretation of slope remains the same, assuming that all other variables are at fixed values. --- # Cautions .left-column[ A model can be statistically significant but explain very little of the response variable. An example: Many restaurants in the USA have a policy *a tip rate of 18% will be charged to dining parties of six or more*. This comes from a linear model, like this: ] .right-column[ ``` Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 18.3191 2.0750 8.829 2.44e-16 *** size -0.9625 0.4217 -2.282 0.0234 * sexMale -0.8543 0.8348 -1.023 0.3072 smokerYes 0.3637 0.8497 0.428 0.6690 daySat -0.1773 1.8341 -0.097 0.9231 daySun 1.6672 1.9023 0.876 0.3817 dayThur -1.8176 2.3194 -0.784 0.4340 timeLunch 2.3371 2.6118 0.895 0.3718 --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 (Dispersion parameter for gaussian family taken to be 36.79008) Null deviance: 9063.4 on 243 degrees of freedom Residual deviance: 8682.5 on 236 degrees of freedom AIC: 1582 Number of Fisher Scoring iterations: 2 ``` ] --- # Interpretation The only important variable in the model is `Size`. `$$\mbox{Tip percentage} = 18.3 - 0.96\times\mbox{Size of the dining party}$$` For each additional member in the dining party, the tip % decreases by about 1%. But look at deviance ( `\(8682.5\)` ) relative to the null deviance ( `\(9063.4\)` ). There is very little difference between the two, which means that size of the dining party explains very little of the variation in tip percentage. --- If we prefer to use `\(R^2\)` use the `lm` function instead: ``` Call: lm(formula = tip_pct ~ size, data = tips) Residuals: Min 1Q Median 3Q Max -13.039 -3.077 -0.608 3.148 54.432 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 18.4375 1.1191 16.475 <2e-16 *** size -0.9173 0.4085 -2.245 0.0256 * --- Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 Residual standard error: 6.057 on 242 degrees of freedom Multiple R-squared: 0.02041, Adjusted R-squared: 0.01636 F-statistic: 5.042 on 1 and 242 DF, p-value: 0.02565 ``` The model is statistically significant but it explains only 2% of the variation in tip percentage. It is practically useless. There are a lot of other factors that affect tips. However, restauranteurs have picked up on the relationship and instituted a convenient policy to guarantee a minimal tip intake with larger dining parties. --- # Make a plot  --- # Regression trees - Regression (decision) trees recursively partition the data, and use the average response value of each partition as the model estimate - Computationally intensive technique, involves examining ALL POSSIBLE partitions. - Chooses the BEST partition by optimizing a criteria - For regression, with a quantitative response variable, the criteria is called ANOVA: `$$SS_T-(SS_L+SS_R)$$` where `\(SS_T = \sum (y_i-\bar{y})^2\)`, and `\(SS_L, SS_R\)` are the equivalent values for the two subsets created by partitioning. --- # What it looks like Here's a synthetic data set for illustration  --- Model ```r df_rp <- rpart(y~x, data=df) df_rp n= 100 node), split, n, deviance, yval * denotes terminal node 1) root 100 2.26392100 0.046658990 2) x>=0.2789237 20 0.14061080 -0.132608100 4) x>=0.3936632 8 0.03452376 -0.185497100 * 5) x< 0.3936632 12 0.06879035 -0.097348760 * 3) x< 0.2789237 80 1.31989300 0.091475770 6) x>=-0.4125869 68 0.94100140 0.067680920 12) x< 0.04880311 52 0.56644400 0.045942920 24) x>=-0.2610339 31 0.29105710 -0.001481586 48) x>=-0.07853794 14 0.20666590 -0.034887260 * 49) x< -0.07853794 17 0.05590193 0.026028970 * 25) x< -0.2610339 21 0.10274290 0.115950500 * 13) x>=0.04880311 16 0.27012590 0.138329400 * 7) x< -0.4125869 12 0.12221610 0.226313300 * ``` --- # Model decision tree  Next, picture the model on the data --- # Splits ``` count ncat improve index adj x 100 1 0.35487877 0.27892366 0 x 20 1 0.26524753 0.39366322 0 x 80 1 0.19446662 -0.41258686 0 x 68 -1 0.11097910 0.04880311 0 x 52 1 0.30478553 -0.26103391 0 x 31 1 0.09788205 -0.07853794 0 ``` ---  ---  ---  ---  ---  ---  ---  --- # When do we stop? - Its an algorithm. Why did it stop at 7 groups? - Stopping rules ar needed, else the algorithm will keep fitting until every observartion is in its own group. - Control parameters set stopping points: + minsplit: minimum number of points in a node that algorithm is allowed to split + minbucket: minimum number of points in a terminal node - In addition, we can also look at the change in value of `\(SS_T-(SS_L+SS_R)\)` at each split, and if the change is too *small*, stop. To decide on a suitable value for *small* a cross-validation procedure is used. --- # Stop points in example model ``` List of 9 $ minsplit : int 20 $ minbucket : num 7 $ cp : num 0.01 $ maxcompete : int 4 $ maxsurrogate : int 5 $ usesurrogate : int 2 $ surrogatestyle: int 0 $ maxdepth : int 30 $ xval : int 10 ``` --- # Changing control parameters ```r df_rp <- rpart(y~x, data=df, control = rpart.control(minsplit=5, minbucket = 2)) df_rp n= 100 node), split, n, deviance, yval * denotes terminal node 1) root 100 2.26392100 0.046658990 2) x>=0.2789237 20 0.14061080 -0.132608100 4) x>=0.3936632 8 0.03452376 -0.185497100 * 5) x< 0.3936632 12 0.06879035 -0.097348760 * 3) x< 0.2789237 80 1.31989300 0.091475770 6) x>=-0.4125869 68 0.94100140 0.067680920 12) x< 0.04880311 52 0.56644400 0.045942920 24) x>=-0.2610339 31 0.29105710 -0.001481586 48) x>=-0.07853794 14 0.20666590 -0.034887260 96) x< -0.008211745 7 0.10571210 -0.096719830 * 97) x>=-0.008211745 7 0.04742810 0.026945310 * 49) x< -0.07853794 17 0.05590193 0.026028970 * 25) x< -0.2610339 21 0.10274290 0.115950500 * 13) x>=0.04880311 16 0.27012590 0.138329400 26) x>=0.1518302 5 0.05338438 0.010833720 * 27) x< 0.1518302 11 0.09852226 0.196282000 54) x< 0.09397898 5 0.02736176 0.117667800 * 55) x>=0.09397898 6 0.01450874 0.261793800 * 7) x< -0.4125869 12 0.12221610 0.226313300 14) x>=-0.456696 5 0.01695255 0.162315200 * 15) x< -0.456696 7 0.07015715 0.272026100 * ``` --- ```r df_rp <- rpart(y~x, data=df, control = rpart.control(minsplit=30, minbucket = 10)) df_rp n= 100 node), split, n, deviance, yval * denotes terminal node 1) root 100 2.26392100 0.046658990 2) x>=0.2789237 20 0.14061080 -0.132608100 * 3) x< 0.2789237 80 1.31989300 0.091475770 6) x>=-0.4125869 68 0.94100140 0.067680920 12) x< 0.04880311 52 0.56644400 0.045942920 24) x>=-0.2610339 31 0.29105710 -0.001481586 48) x>=-0.07853794 14 0.20666590 -0.034887260 * 49) x< -0.07853794 17 0.05590193 0.026028970 * 25) x< -0.2610339 21 0.10274290 0.115950500 * 13) x>=0.04880311 16 0.27012590 0.138329400 * 7) x< -0.4125869 12 0.12221610 0.226313300 * ``` --- # What's the computation? Illustration showing the calculations made to decide on the first partition.  --- # Residuals  --- # Goodness of fit ```r gof <- printcp(df_rp, digits=3) Regression tree: rpart(formula = y ~ x, data = df) Variables actually used in tree construction: [1] x Root node error: 2.26/100 = 0.0226 n= 100 CP nsplit rel error xerror xstd 1 0.3549 0 1.000 1.022 0.1341 2 0.1134 1 0.645 0.822 0.1193 3 0.0612 2 0.532 0.682 0.0931 4 0.0165 4 0.409 0.559 0.0807 5 0.0126 5 0.393 0.539 0.0737 6 0.0100 6 0.380 0.536 0.0738 ``` The relative error is `\(1-R^2\)`. For this example, after 6 splits it is 0.3802991. So `\(R^2=\)` 0.6197009. --- # Strengths and weaknesses - There are no parametric assumptions underlying partitioning methods - Also means that there is not a nice formula for the model as a result, or inference about populations available - By minimizing sum of squares (ANOVA) we are forcing the partitions to have relatively equal variance. The method could be influenced by outliers, but it would be isolating the effect to one partition. - Because it operates on single variables, it can efficiently handle missing values. --- # Example - OECD PISA, what factors affect reading scores? - 15 year old standardised test scores, Australia, 2015 - Response: math - Predictors: gender, ANXTEST, PARED, JOYSCIE, WEALTH, nbooks, ntvs --- # Linear model ``` Call: lm(formula = math ~ gender + ANXTEST + PARED + JOYSCIE + WEALTH + nbooks + ntvs, data = pisa_au_nomiss, weights = W_FSTUWT) Weighted Residuals: Min 1Q Median 3Q Max -1535.64 -179.23 -11.07 168.42 1336.37 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 388.1974 6.3093 61.527 < 2e-16 *** genderm 5.1320 1.3661 3.757 0.000173 *** ANXTEST -8.0380 0.6956 -11.556 < 2e-16 *** PARED 7.1283 0.3603 19.787 < 2e-16 *** JOYSCIE 21.2261 0.5740 36.981 < 2e-16 *** WEALTH 5.6973 0.8923 6.385 1.78e-10 *** nbooks 14.4634 0.4949 29.226 < 2e-16 *** ntvs -12.1794 1.0491 -11.609 < 2e-16 *** --- Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 Residual standard error: 308 on 12110 degrees of freedom Multiple R-squared: 0.2739, Adjusted R-squared: 0.2735 F-statistic: 652.6 on 7 and 12110 DF, p-value: < 2.2e-16 ``` --- # Regression tree ``` n= 12118 node), split, n, deviance, yval * denotes terminal node 1) root 12118<PHONE_NUMBER> 500.3926 2) JOYSCIE< -0.1626 4631 465314500 464.3309 4) nbooks< 2.5 1512 117372100 432.4937 * 5) nbooks>=2.5 3119 314200900 477.2861 10) PARED< 14.5 1755 146736900 461.0853 * 11) PARED>=14.5 1364 149348500 496.5171 * 3) JOYSCIE>=-0.1626 7487 948249800 521.3828 6) PARED< 14.5 3725 400876300 495.4454 12) nbooks< 2.5 1049 100022100 462.9746 * 13) nbooks>=2.5 2676 276643400 506.8371 * 7) PARED>=14.5 3762 464959900 543.9905 14) nbooks< 3.5 1480 177490100 516.6616 * 15) nbooks>=3.5 2282 252445100 561.0575 * ``` ---  --- # Most important variable  --- # All the variables  --- class: inverse middle # Share and share alike
This work is licensed under a Creative Commons Attribution 4.0 International License.


Online Transactions
Move to a smart way to transfer funds, pay bills, and make payments for Credit Cards & Loans.
Take care of recurring payments for Insurance, Mobile and Telephone by using standing instructions..
Statement on E-mail
Tired of filing your paper statements? Move to secure and printable online statements delivered on your E-mail ID.
Use them while filing tax returns, keeping track of your money, planning your expenses and more.


Follow these steps to purchase QuantConnect Credit (QCC):
- Log in to the Algorithm Lab.
- In the left navigation bar, click Organization > Billing.
- On the Billing page, scroll down to the Organization Credit (QCC) section and then click Purchase Credit.
- Select a credit pack and then click Continue.
- If your preferred organization has a credit card and you would like to charge that card, click Purchase. If your preferred organization doesn't have a credit card, enter the credit card details and then click Purchase.
Only the preferred organization can be charged when purchasing QCC. If you would like to charge a different organization that you are a member of, set the organization you would like to charge as your preferred organization.
If you successfully purchase QCC, the Credit Balance section on the organization homepage displays the new balance.


--- layout: post title: Roasted Eggplant date: type: post parent_id: '0' published: false image: assets/images/post-img/ status: draft categories: - Etc. tags: [] meta: _oembed_bb66aae799050582f7d98566cda5d183: '
' _oembed_time_bb66aae799050582f7d98566cda5d183: '1440694946' author: login: mkelley email<EMAIL_ADDRESS>display_name: Mike first_name: Mike last_name: Kelley ---
[embed]https://instagram.com/p/rNsPt0DOMF/?taken-by=iomike[/embed]


The Aggregation relationship indicates that a concept groups a number of other concepts.
In contrast to the Composition relationship, an object can be part of more than one Aggregation.
Aggregation is always possible between two instances of the same concept.
Structural.
A Car Insurance Business Product aggregates a Business Contract and some Business Services.


addSound:
Adds a new sound to the game. The argument should be a string with the URL to the sound file.
self addSound: 'path/to/audioFile.ogg'.
backgroundColor:
Defines the background color of the game canvas in HTML color format.
self backgroundColor: '#45FF32'.
clearCanvas
Clears the whole canvas. All sprites and drawings will be erased, but not the background. This method is usually called from within #draw, right before repainting all sprites and drawings in their new state.
self clearCanvas.
self drawSprite: aSprite.
draw
This method is called at every game cycle, here you should define the drawing of sprites and other graphic elements. Don't forget to clear the canvas before re-drawing sprites, if your game requires so.
MyGame >> draw
self
clearCanvas;
drawSprite: mySprite;
drawSprite: myOtherSprite;
drawSpriteCollection: manySprites.
drawSprite:
Paints the sprite given by the argument.
self drawSprite: badGuy.
drawSpriteCollection:
Paints all sprites contained in the collection given by the argument.
self drawSpriteCollection: monsters.
end
Ends the current game. Stops the game cycle. Can be called from #step to end the game when the given endgame conditions are satisfied.
MyGame >> step
(...)
self mainCharacter isDead ifTrue: [ self end ]
(...)
everyStepNumber:do:
Every number of steps given by the first argument, it evaluates the block given by the second argument.
self everyStepNumber: 500 do: [ self increaseDifficulty ].
fps:
Defines the frames per second at which the game is going to attempt to be rendered. Take in account that the ultimate FPS rating will be given by the particular configuration of the client's hardware and software. Can be called from #startGame.
MyGame >> startGame
self fps: 30.
gameLoop
Controls the game cycles. Do not override this method, use #draw and #step instead.
gameOver
Answers true if the game is over, false otherwise.
self gameOver ifTrue: [ self showScore ].
height
Returns the height of the game canvas in pixels.
height:
Defines the height of the game canvas in pixels. Can be called from #startGame.
MyGame >> StartGame
self height: 600.
keyDown:
Is triggered when a key is pressed. Do not use this method, use the event handler #whileKeyPressed:do: instead.
keyUp:
Is triggered when a key is released. Do not use this method, use the event handler #whileKeyPressed:do: instead.
keys
Returns an array of key states. Do not use this method, use the event handler #whileKeyPressed:do: instead.
mouseDown:
Is triggered when a mouse button is pressed. Do not use this method, use the event handlers #whileMouseDownDo:, #whileMouseUpDo:, #onMouseClickDo:, #onMouseDownDo: and #onMouseUpDo:instead.
mouseMove:
Is triggered when the mouse pointer moves. Do not use this method, use the event handlers #whileMouseDownDo:, #whileMouseUpDo:, #onMouseClickDo:, #onMouseDownDo: and #onMouseUpDo:instead.
mousePosition
Returns the current mouse position, relative to the game canvas origin, as a point.
mySprite centre: self mousePosition.
mouseUp:
Is triggered when a mouse button is released. Do not use this method, use the event handlers #whileMouseDownDo:, #whileMouseUpDo:, #onMouseClickDo:, #onMouseDownDo: and #onMouseUpDo:instead.
onMouseClickDo:
It evaluates the block given by the argument when the mouse is clicked.
MyGame >> step
self onMouseClickDo: [ spaceShip shoot ].
onMouseDownDo:
It evaluates the block given by the argument when a mouse button is pressed.
MyGame >> step
self onMouseDownDo: [ selectionRectangle origin: self mousePosition ].
onMouseUpDo:
It evaluates the block given by the argument when a mouse button is released.
MyGame >> step
self onMouseUpDo: [ selectionRectangle destination: self mousePosition ].
soundNamed:
Retrieves the sound with the named as the argument indicates. The sound name is, by default, the name of the sound file it points to minus its extension.
self addSound: 'path/to/audioFile.ogg'.
(self soundNamed: 'audioFile') play.
startGame
This method should be overriden to define the game's initial conditions, such as the frames per second, the game canvas size, background, sounds, etc.
MyGame >> startGame
self
fps: 20;
width: 800;
height: 600;
backgroundColor: 'black';
addSound: 'sounds/explosion.ogg';
addSound: 'sounds/die.ogg';
addSound: 'sounds/backgroundMusic.ogg'.
(self soundNamed: 'backgroundMusic') loop.
step
This method should be overriden to define what has to be done at each game cycle, or step. This method should control posititions, collisions, mouse and keyboard events, etc. This method should not deal with any graphic properties, these should be dealt with by #draw.
MyGame >> step
self
handleCollisions;
handleKeyStrokes
updatePositions.
goodGuy isDead ifTrue: [ self end ].
stepCount
Returns the number of cycles, or steps, that have been processed since the game started.
whileKeyPressed:do:
While the key given by the first argument is pressed, it evaluates the block given by the second argument.
MyGame >> step
self whileKeyPressed: Key upArrow do: [ superheroe moveCentreBy: (0 @ -1) ].
whileMouseDownDo:
It evaluates the block given by the argument while a mouse button is pressed down.
MyGame >> step
self whileMouseDownDo: [ helicopter goUp ].
whileMouseUpDo:
It evaluates the block given by the argument while a mouse button is not being pressed.
MyGame >> step
self whileMouseUpDo: [ helicopter fallDown ].
width
Returns the width of the game canvas in pixels.
width:
Defines the width of the game canvas in pixels.
self width: 800;


Posted on 28/05/2017 at 10:00 PM by The Vibe.
Community Bonding Period is roughly a 4-week period before the coding period wherein the selected GSoC students and mentors get to know more about each other, and also discuss more about the project implementation. This year, SciRuby ( GitHub | Website ) has selected 3 students - Prasun, Shekar and myself. As Shekhar & myself were selected for the same project idea, we had to split the project idea into 2 components and re-draft our timeline schedules.
A consensus was reached that the project will be split into two parts namely
daru-io
and daru-view
, with the former being done by me and the latter
being done by Shekhar.
Through this one hour long discussion, we shared the main highlights of each other's proposals that help with my daru-io part as well as Shakhar's daru-view part. We also had a discussion regarding which libraries could be used for various use cases, and whether we could integrate daru-io and daru-views through a use-case like a 'Download' option in Ruby web frameworks like Rails.
This discussion was essentially a continuation of the previous video
conference. We discussed more regarding adding more features in the same
timeline, now that our work has been split well. The consensus was to add
more support to both daru-io and daru-views. That is, more Import-Export
modules will be added to daru-io
during the colloborated timeline, while more
plotting library support will be added to daru-view
.
Through this video conference, we discussed about both our re-drafted proposals with mentors Sameer and Victor. By running through our proposal week by week and module by module, we made sure that our timelines have been re-drafted feasibly, and without any clashes. The colloborated proposal now has the following deliverables :
This was an offline meetup that took place between GSoCers from Chennai, to discuss about their projects, coding, colleges, TV series and what not! It was good to meet a couple of like-minded people with similar interests.


Log In
|
Create Account
VICTORINOX
About Us
|
Victorinox Stories
|
Customer Service
|
Store Locator
|
Corporate Gifts
Swiss Army Knife
Category
Swiss Army Knives
Classic
Delemont Collection
Victorinox Tomo
Pocket Knives
Golf Tools
Tools for Horticulture
Swiss Tools
Swiss Cards
Accesories
Limited Edition
Cutlery
Category
Sharpening Tools
Cut Resistant Gloves
Household Knives
Kitchen Utensils
Professional Knives
Forged Chef's Cutlery
Collection
Time Pieces
Category
New Products
Limited Edition
Mechanical
Chronograph
Collection
Travel Gear
Category
Luggage
Business
Everyday
Accesories
Collection
Travel Gear
Fashion
Category
Jeans
Jackets
Shoes
Biker Gloves
Fragrances
Category
For Him
For Her
Log Into Your Account
User ID*:
Password*:
Remember Me
Create Accounts
Not sure why you should open an account? Opening a Victorinox account allows you to: Post and rate reviews, share your story, receive emails and updates in your inbox and customize your online Victorinox experience.
Create Account


Step 1.
Describe commands, events, and state of entities using Protobuf.
// A command to create a new task.
message CreateTask {
TaskId id = 1;
string name = 2 [(required) = true];
string description = 3;
}
...
// A new task has been created.
message TaskCreated {
TaskId id = 1;
string name = 2 [(required) = true];
string description = 3;
}
...
message Task {
(entity).kind = AGGREGATE;
TaskId id = 1;
string name = 2 [(required) = true];
string description = 3;
DeveloperId assignee = 4;
}
Step 2.
Java, JavaScript, and C++ are currently supported.
Step 3.
Focus on business logic rather than “plumbing”.
A Command
will be delivered to only one Aggregate
.
Projection
s will get all Event
s they need.
ProcessManager
s will cover more complex scenarios.
Storage, message delivery, and other environment matters are isolated from the main code.
final class TaskAggregate
extends Aggregate<TaskId, Task, TaskVBuilder> {
...
@Assign
TaskCreated handle(CreateTask cmd, CommandContext ctx) {
return TaskCreated
.vBuilder()
.setId(cmd.getId())
.setName(cmd.getName())
.setOwner(ctx.getActor())
.build();
}
...
}
final class TaskProjection
extends Projection<TaskId, TaskItem, TaskItemVBuilder> {
...
@Subscribe
void on(TaskCreated e) {
builder().setId(e.getId())
.setName(e.getName())
}
@Subscribe
void on(TaskCompleted e, EventContext ctx) {
builder().setWhenDone(ctx.getTimestamp());
}
}
Step 4.
In-memory and JDBC-based storage implementations allow to implement and test the core logic quickly. Adopt your application to selected deployment environment(s) with a few lines of code.
The code is automatically generated for all the languages of
your project, as you update the model.
Forget about missed hashCode()
or equals()
.
Constraints defined in a business model are automatically checked for commands, events, and entity states.
With CQRS and Event-Driven Architecture you can separate development workflows. More experienced team members can concentrate on the core domain and the write-side tasks while the read–side and UI are created by the rest of the team.
Concepts from the DDD books, such as
Aggregate
,
Projection
,
ProcessManager
,
Repository
are right in the code.
Ever guessed how to cook a BoundedContext
?
Guess no more!
Should you need CustomerId
or
WorkEstimate
value, you get it within seconds,
for multiple languages. You can also have binary storage format
and automatic JSON support.
Add and remove fields while keeping binary compatibility with older code;
handle new opportunities with oneof
, natively provided by Protobuf.
Build new Projections
based on the whole event history of the system.
All the data types are immutable, which makes it easy to cache and share. Mutations are performed only in response to incoming messages using clearly defined cycles.
The framework promotes development of storage- and platform-agnostic code. You can start with JDBC and later switch to Google Cloud Platform Datastore simply changing a few lines of code.
Use freely in closed-source projects. You are also welcome to contribute to improving our framework.


1. Download each form uploaded by clicking
2. Open and confirm it’s correct by clicking
3. If the form is NOT the correct one, click on
You will be taken to STEP 2 to upload the correct form again.
4. After each form has been verfied by the admin, the checkmark will turn from yellow to green.


|
||||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |
| Class Summary | |
| DeploymentDescriptor | Apache SOAP v2.x Deployment Descriptor Support classes The way this is intended to work is simple: load a v2.x deployment descriptor, and this object model (via the V2DDDeployableItem class will convert the Service definition into something that Axis can handle. |
| V2DDConstants | |
| V2DDDeployableItem | This is the class that actually bridges the gap between SOAP 2.x and Axis. |
| V2DDElement | |
| V2DDFaultListener | |
| V2DDMap | |
| V2DDMappings | |
| V2DDOption | |
| V2DDProvider | |
| V2DDService |
| Exception Summary | |
| V2DDException |
|
||||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |


Money game. How should Red play 44?
pips Red=135 White=154
(CorrectAnswer= 0/0, ErrorScore= 0)
Without the Quiz Factor I think most people would play 18/10(2)* and indeed I didn't give the position a second thought when playing it.
However, 18/14(2), 8/4(2) and 18/10(2)* both win around 80% of the time but 18/14(2), 8/4(2) wins enough extra gammons to make it the right play, if not by much. 18/10(2)* is not an error in XG terms but it is an incorrect play.
I included this position just to remind you not to play on automatic – even ‘obvious' plays are sometimes wrong.
However, 18/14(2), 8/4(2) and 18/10(2)* both win around 80% of the time but 18/14(2), 8/4(2) wins enough extra gammons to make it the right play, if not by much. 18/10(2)* is not an error in XG terms but it is an incorrect play.
I included this position just to remind you not to play on automatic – even ‘obvious' plays are sometimes wrong.
1. Cubeful 2-ply 18/14(2) 8/4(2) Eq.: +0.679 0.776 0.231 0.003 - 0.224 0.032 0.000 2. Cubeful 2-ply 18/10*(2) Eq.: +0.675 (-0.003) 0.778 0.225 0.005 - 0.222 0.035 0.000 3. Cubeful 2-ply 8/4(2) 6/2(2) Eq.: +0.602 (-0.076) 0.716 0.315 0.005 - 0.284 0.053 0.001 4. Cubeful 2-ply 18/10* 8/4(2) Eq.: +0.593 (-0.085) 0.720 0.291 0.012 - 0.280 0.054 0.001 5. Cubeful 0-ply 18/14(2) 6/2(2) Eq.: +0.533 (-0.146) 0.736 0.193 0.002 - 0.264 0.044 0.000


new Weapon(game, parent)
The Weapon Plugin provides the ability to easily create a bullet pool and manager.
Weapons fire Phaser.Bullet objects, which are essentially Sprites with a few extra properties. The Bullets are enabled for Arcade Physics. They do not currently work with P2 Physics.
The Bullets are created inside of Weapon.bullets
, which is a Phaser.Group instance. Anything you
can usually do with a Group, such as move it around the display list, iterate it, etc can be done
to the bullets Group too.
Bullets can have textures and even animations. You can control the speed at which they are fired, the firing rate, the firing angle, and even set things like gravity for them.
A small example, assumed to be running from within a Phaser.State create method.
var weapon = this.add.weapon(10, 'bullet');
weapon.fireFrom.set(300, 300);
this.input.onDown.add(weapon.fire, this);
Parameters:
| Name | Type | Description |
|---|---|---|
game |
Phaser.Game | A reference to the current Phaser.Game instance. |
parent |
Phaser.PluginManager | The Phaser Plugin Manager which looks after this plugin. |
- Source - plugins/weapon/WeaponPlugin.js, line 31
Members
-
<static, constant> KILL_CAMERA_BOUNDS :integer
-
A
bulletKillType
constant that automatically kills the bullets when they leave theCamera.bounds
rectangle.- Source - plugins/weapon/WeaponPlugin.js, line 443
-
<static, constant> KILL_DISTANCE :integer
-
A
bulletKillType
constant that automatically kills the bullets after they exceed thebulletDistance
from their original firing position.- Source - plugins/weapon/WeaponPlugin.js, line 429
-
<static, constant> KILL_LIFESPAN :integer
-
A
bulletKillType
constant that automatically kills the bullets when theirbulletLifespan
expires.- Source - plugins/weapon/WeaponPlugin.js, line 421
-
<static, constant> KILL_NEVER :integer
-
A
bulletKillType
constant that stops the bullets from ever being destroyed automatically.- Source - plugins/weapon/WeaponPlugin.js, line 414
-
<static, constant> KILL_STATIC_BOUNDS :integer
-
A
bulletKillType
constant that automatically kills the bullets when they leave theWeapon.bounds
rectangle.- Source - plugins/weapon/WeaponPlugin.js, line 457
-
<static, constant> KILL_WEAPON_BOUNDS :integer
-
A
bulletKillType
constant that automatically kills the bullets when they leave theWeapon.bounds
rectangle.- Source - plugins/weapon/WeaponPlugin.js, line 436
-
<static, constant> KILL_WORLD_BOUNDS :integer
-
A
bulletKillType
constant that automatically kills the bullets when they leave theWorld.bounds
rectangle.- Source - plugins/weapon/WeaponPlugin.js, line 450
-
_hasFired :boolean
-
Internal multiFire test flag.
- Source - plugins/weapon/WeaponPlugin.js, line 359
-
autoExpandBulletsGroup :boolean
-
Should the bullet pool run out of bullets (i.e. they are all in flight) then this boolean controls if the Group will create a brand new bullet object or not.
- Source - plugins/weapon/WeaponPlugin.js, line 46
-
autofire :boolean
-
Will this weapon auto fire? If set to true then a new bullet will be fired based on the
fireRate
value.- Source - plugins/weapon/WeaponPlugin.js, line 53
-
bounds :Phaser.Rectangle
-
This Rectangle defines the bounds that are used when determining if a Bullet should be killed or not. It's used in combination with
Weapon.bulletKillType
when that is set to eitherPhaser.Weapon.KILL_WEAPON_BOUNDS
orPhaser.Weapon.KILL_STATIC_BOUNDS
. If you are not using either of these kill types then the bounds are ignored. If you are tracking a Sprite or Point then the bounds are centered on that object every frame.- Source - plugins/weapon/WeaponPlugin.js, line 266
-
bulletAngleOffset :number
-
An optional angle offset applied to the Bullets when they are launched. This is useful if for example your bullet sprites have been drawn facing up, instead of to the right, and you want to fire them at an angle. In which case you can set the angle offset to be 90 and they'll be properly rotated when fired.
- Source - plugins/weapon/WeaponPlugin.js, line 153
-
bulletAngleVariance :number
-
This is a variance added to the angle of Bullets when they are fired. If you fire from an angle of 90 and have a
bulletAngleVariance
of 20 then the actual angle of the Bullets will be between 70 and 110 degrees. This is a quick way to add a great 'spread' effect to a Weapon.- Source - plugins/weapon/WeaponPlugin.js, line 162
-
bulletAnimation :string
-
The string based name of the animation that the Bullet will be given on launch. This is set via
Weapon.addBulletAnimation
.- Source - plugins/weapon/WeaponPlugin.js, line 112
-
bulletClass :function
-
The Class of the bullets that are launched by this Weapon. Defaults to Phaser.Bullet, but can be overridden before calling
createBullets
and set to your own class type.It should be a constructor function accepting
(game, x, y, key, frame)
.- Source - plugins/weapon/WeaponPlugin.js, line 1275
-
bulletCollideWorldBounds :boolean
-
Should bullets collide with the World bounds or not?
- Source - plugins/weapon/WeaponPlugin.js, line 1367
-
bulletFrame :string|integer
-
The Texture Frame that the Bullets use when rendering. Changing this has no effect on bullets in-flight, only on newly spawned bullets.
Type:
- string | integer
- Source - plugins/weapon/WeaponPlugin.js, line 221
-
bulletFrameCycle :boolean
-
If you've added a set of frames via
Weapon.setBulletFrames
then you can optionally chose for each Bullet fired to use the next frame in the set. The frame index is then advanced one frame until it reaches the end of the set, then it starts from the start again. Cycling frames like this allows you to create varied bullet effects via sprite sheets.- Source - plugins/weapon/WeaponPlugin.js, line 129
-
bulletFrameRandom :boolean
-
If you've added a set of frames via
Weapon.setBulletFrames
then you can optionally chose for each Bullet fired to pick a random frame from the set.- Source - plugins/weapon/WeaponPlugin.js, line 119
-
<internal> bulletFrames :Array
-
This array stores the frames added via
Weapon.setBulletFrames
.- Internal:
- This member is internal (protected) and may be modified or removed in the future.
- Source - plugins/weapon/WeaponPlugin.js, line 282
-
bulletGravity :Phaser.Point
-
This is the amount of gravity added to the Bullets physics body when fired. Gravity is expressed in pixels / second / second.
- Source - plugins/weapon/WeaponPlugin.js, line 199
-
bulletInheritSpriteSpeed :boolean
-
When a Bullet is fired it can optionally inherit the velocity of the
trackedSprite
if set.- Source - plugins/weapon/WeaponPlugin.js, line 105
-
bulletKey :string
-
The Texture Key that the Bullets use when rendering. Changing this has no effect on bullets in-flight, only on newly spawned bullets.
- Source - plugins/weapon/WeaponPlugin.js, line 214
-
bulletKillDistance :number
-
If you've set
bulletKillType
toPhaser.Weapon.KILL_DISTANCE
this controls the distance the Bullet can travel before it is automatically killed. The distance is given in pixels.- Source - plugins/weapon/WeaponPlugin.js, line 192
-
bulletKillType :integer
-
This controls how the bullets will be killed. The default is
Phaser.Weapon.KILL_WORLD_BOUNDS
.There are 7 different "kill types" available:
Phaser.Weapon.KILL_NEVER
The bullets are never destroyed by the Weapon. It's up to you to destroy them via your own code.Phaser.Weapon.KILL_LIFESPAN
The bullets are automatically killed when theirbulletLifespan
amount expires.Phaser.Weapon.KILL_DISTANCE
The bullets are automatically killed when they exceedbulletDistance
pixels away from their original launch position.Phaser.Weapon.KILL_WEAPON_BOUNDS
The bullets are automatically killed when they no longer intersect with theWeapon.bounds
rectangle.Phaser.Weapon.KILL_CAMERA_BOUNDS
The bullets are automatically killed when they no longer intersect with theCamera.bounds
rectangle.Phaser.Weapon.KILL_WORLD_BOUNDS
The bullets are automatically killed when they no longer intersect with theWorld.bounds
rectangle.Phaser.Weapon.KILL_STATIC_BOUNDS
The bullets are automatically killed when they no longer intersect with theWeapon.bounds
rectangle. The difference between static bounds and weapon bounds, is that a static bounds will never be adjusted to match the position of a tracked sprite or pointer.
- Source - plugins/weapon/WeaponPlugin.js, line 1304
-
bulletLifespan :number
-
If you've set
bulletKillType
toPhaser.Weapon.KILL_LIFESPAN
this controls the amount of lifespan the Bullets have set on launch. The value is given in milliseconds. When a Bullet hits its lifespan limit it will be automatically killed.- Source - plugins/weapon/WeaponPlugin.js, line 185
-
bulletRotateToVelocity :boolean
-
Bullets can optionally adjust their rotation in-flight to match their velocity. This can create the effect of a bullet 'pointing' to the path it is following, for example an arrow being fired from a bow, and works especially well when added to
bulletGravity
.- Source - plugins/weapon/WeaponPlugin.js, line 207
-
bullets :Phaser.Group
-
This is the Phaser.Group that contains all of the bullets managed by this plugin.
- Source - plugins/weapon/WeaponPlugin.js, line 39
-
bulletSpeed :number
-
The speed at which the bullets are fired. This value is given in pixels per second, and is used to set the starting velocity of the bullets.
- Source - plugins/weapon/WeaponPlugin.js, line 169
-
bulletSpeedVariance :number
-
This is a variance added to the speed of Bullets when they are fired. If bullets have a
bulletSpeed
value of 200, and abulletSpeedVariance
of 50 then the actual speed of the Bullets will be between 150 and 250 pixels per second.- Source - plugins/weapon/WeaponPlugin.js, line 177
-
bulletWorldWrap :boolean
-
Should the Bullets wrap around the world bounds? This automatically calls
World.wrap
on the Bullet each frame. See the docs for that method for details.- Source - plugins/weapon/WeaponPlugin.js, line 136
-
bulletWorldWrapPadding :integer
-
If
bulletWorldWrap
is true then you can provide an optional padding value with this property. It's added to the calculations determining when the Bullet should wrap around the world or not. The value is given in pixels.- Source - plugins/weapon/WeaponPlugin.js, line 144
-
fireAngle :integer
-
The angle at which the bullets are fired. This can be a const such as Phaser.ANGLE_UP or it can be any number from 0 to 360 inclusive, where 0 degrees is to the right.
- Source - plugins/weapon/WeaponPlugin.js, line 99
-
fireFrom :Phaser.Rectangle
-
This is a Rectangle from within which the bullets are fired. By default it's a 1x1 rectangle, the equivalent of a Point. But you can change the width and height, and if larger than 1x1 it'll pick a random point within the rectangle to launch the bullet from.
- Source - plugins/weapon/WeaponPlugin.js, line 92
-
fireLimit :number
-
The maximum number of shots that this Weapon is allowed to fire before it stops. When the limit is his the
Weapon.onFireLimit
Signal is dispatched. You can reset the shot counter viaWeapon.resetShots
.- Source - plugins/weapon/WeaponPlugin.js, line 69
-
fireRate :number
-
The rate at which this Weapon can fire. The value is given in milliseconds.
- Source - plugins/weapon/WeaponPlugin.js, line 75
-
fireRateVariance :number
-
This is a modifier that is added to the
fireRate
each update to add variety to the firing rate of the Weapon. The value is given in milliseconds. If you've afireRate
of 200 and afireRateVariance
of 50 then the actual firing rate of the Weapon will be between 150 and 250.- Source - plugins/weapon/WeaponPlugin.js, line 84
-
multiFire :boolean
-
If you want this Weapon to be able to fire more than 1 bullet in a single update, then set this property to
true
. Whentrue
the Weapon plugin won't set the shot / firing timers until thepostRender
phase of the game loop. This means you can callfire
(and similar methods) as often as you like in one single game update.- Source - plugins/weapon/WeaponPlugin.js, line 352
-
onFire :Phaser.Signal
-
The onFire Signal is dispatched each time
Weapon.fire
is called, and a Bullet is successfully launched. The callback is set two arguments: a reference to the bullet sprite itself, and a reference to the Weapon that fired the bullet.- Source - plugins/weapon/WeaponPlugin.js, line 306
-
onFireLimit :Phaser.Signal
-
The onFireLimit Signal is dispatched if
Weapon.fireLimit
is > 0, and a bullet launch takes the number of shots fired to equal the fire limit. The callback is sent two arguments: A reference to the Weapon that hit the limit, and the value ofWeapon.fireLimit
.- Source - plugins/weapon/WeaponPlugin.js, line 325
-
onKill :Phaser.Signal
-
The onKill Signal is dispatched each time a Bullet that is in-flight is killed. This can be the result of leaving the Weapon bounds, an expiring lifespan, or exceeding a specified distance. The callback is sent one argument: A reference to the bullet sprite itself.
- Source - plugins/weapon/WeaponPlugin.js, line 315
-
shots :number
-
The total number of bullets this Weapon has fired so far. You can limit the number of shots allowed (via
fireLimit
), and reset this total viaWeapon.resetShots
.- Source - plugins/weapon/WeaponPlugin.js, line 61
-
trackedPointer :Phaser.Pointer
-
The Pointer currently being tracked by the Weapon, if any. This is set via the
Weapon.trackPointer
method.- Source - plugins/weapon/WeaponPlugin.js, line 341
-
trackedSprite :Phaser.Sprite|Object
-
The Sprite currently being tracked by the Weapon, if any. This is set via the
Weapon.trackSprite
method.Type:
- Phaser.Sprite | Object
- Source - plugins/weapon/WeaponPlugin.js, line 333
-
trackOffset :Phaser.Point
-
The Track Offset is a Point object that allows you to specify a pixel offset that bullets use when launching from a tracked Sprite or Pointer. For example if you've got a bullet that is 2x2 pixels in size, but you're tracking a Sprite that is 32x32, then you can set
trackOffset.x = 16
to have the bullet launched from the center of the Sprite.- Source - plugins/weapon/WeaponPlugin.js, line 378
-
trackRotation :boolean
-
If the Weapon is tracking a Sprite, should it also track the Sprites rotation? This is useful for a game such as Asteroids, where you want the weapon to fire based on the sprites rotation.
- Source - plugins/weapon/WeaponPlugin.js, line 368
-
x :number
-
The x coordinate from which bullets are fired. This is the same as
Weapon.fireFrom.x
, and can be overridden by theWeapon.fire
arguments.- Source - plugins/weapon/WeaponPlugin.js, line 1392
-
y :number
-
The y coordinate from which bullets are fired. This is the same as
Weapon.fireFrom.y
, and can be overridden by theWeapon.fire
arguments.- Source - plugins/weapon/WeaponPlugin.js, line 1414
Methods
-
addBulletAnimation(name, frames, frameRate, loop, useNumericIndex) → {Phaser.Weapon}
-
Adds a new animation under the given key. Optionally set the frames, frame rate and loop. The arguments are all the same as for
Animation.add
, and work in the same way.Weapon.bulletAnimation
will be set to this animation after it's created. From that point on, all bullets fired will play using this animation. You can swap between animations by calling this method several times, and then just changing theWeapon.bulletAnimation
property to the name of the animation you wish to play for the next launched bullet.If you wish to stop using animations at all, set
Weapon.bulletAnimation
to '' (an empty string).Parameters:
Name Type Argument Default Description name
string The unique (within the Weapon instance) name for the animation, i.e. "fire", "blast".
frames
Array <optional>
null An array of numbers/strings that correspond to the frames to add to this animation and in which order. e.g. [1, 2, 3] or ['run0', 'run1', run2]). If null then all frames will be used.
frameRate
number <optional>
60 The speed at which the animation should play. The speed is given in frames per second.
loop
boolean <optional>
false Whether or not the animation is looped or just plays once.
useNumericIndex
boolean <optional>
true Are the given frames using numeric indexes (default) or strings?
Returns:
The Weapon Plugin.
- Source - plugins/weapon/WeaponPlugin.js, line 1212
-
createBullets(quantity, key, frame, group) → {Phaser.Weapon}
-
This method performs two actions: First it will check to see if the
Weapon.bullets
Group exists or not, and if not it creates it, adding it thegroup
given as the 4th argument.Then it will seed the bullet pool with the
quantity
number of Bullets, using the texture key and frame provided (if any).If for example you set the quantity to be 10, then this Weapon will only ever be able to have 10 bullets in-flight simultaneously. If you try to fire an 11th bullet then nothing will happen until one, or more, of the in-flight bullets have been killed, freeing them up for use by the Weapon again.
If you do not wish to have a limit set, then pass in -1 as the quantity. In this instance the Weapon will keep increasing the size of the bullet pool as needed. It will never reduce the size of the pool however, so be careful it doesn't grow too large.
You can either set the texture key and frame here, or via the
Weapon.bulletKey
andWeapon.bulletFrame
properties. You can also animate bullets, or set them to use random frames. All Bullets belonging to a single Weapon instance must share the same texture key however.Parameters:
Name Type Argument Default Description quantity
integer <optional>
1 The quantity of bullets to seed the Weapon with. If -1 it will set the pool to automatically expand.
key
string <optional>
The Game.cache key of the image that this Sprite will use.
frame
integer | string <optional>
If the Sprite image contains multiple frames you can specify which one to use here.
group
Phaser.Group <optional>
Optional Group to add the object to. If not specified it will be added to the World group.
Returns:
This Weapon instance.
- Source - plugins/weapon/WeaponPlugin.js, line 459
-
debug(x, y, debugBodies)
-
Uses
Game.Debug
to draw some useful information about this Weapon, including the number of bullets both in-flight, and available. And optionally the physics debug bodies of the bullets.Parameters:
Name Type Argument Default Description x
integer <optional>
16 The coordinate, in screen space, at which to draw the Weapon debug data.
y
integer <optional>
32 The coordinate, in screen space, at which to draw the Weapon debug data.
debugBodies
boolean <optional>
false Optionally draw the physics body of every bullet in-flight.
- Source - plugins/weapon/WeaponPlugin.js, line 1250
-
destroy()
-
Destroys this Weapon. It removes itself from the PluginManager, destroys the bullets Group, and nulls internal references.
- Source - plugins/weapon/WeaponPlugin.js, line 605
-
fire(from, x, y, offsetX, offsetY) → {Phaser.Bullet}
-
Attempts to fire a single Bullet. If there are no more bullets available in the pool, and the pool cannot be extended, then this method returns
null
. It will also returnnull
if not enough time has expired since the last time the Weapon was fired, as defined in theWeapon.fireRate
property.Otherwise the first available bullet is selected, launched, and returned.
The arguments are all optional, but allow you to control both where the bullet is launched from, and aimed at.
If you don't provide any of the arguments then it uses those set via properties such as
Weapon.trackedSprite
,Weapon.bulletAngle
and so on.When the bullet is launched it has its texture and frame updated, as required. The velocity of the bullet is calculated based on Weapon properties like
bulletSpeed
.If you wish to fire multiple bullets in a single game update, then set
Weapon.multiFire = true
and you can callfire
as many times as you like, per loop. Multiple fires in a single update only counts once towards theshots
total, but you will still receive a Signal for each bullet.Parameters:
Name Type Argument Default Description from
Phaser.Sprite | Phaser.Point | Object | string <optional>
Optionally fires the bullet from the
x
andy
properties of this object. If set this overridesWeapon.trackedSprite
ortrackedPointer
. Passnull
to ignore it.x
number <optional>
The x coordinate, in world space, to fire the bullet towards. If left as
undefined
, ornull
, the bullet direction is based on its angle.y
number <optional>
The y coordinate, in world space, to fire the bullet towards. If left as
undefined
, ornull
, the bullet direction is based on its angle.offsetX
number <optional>
0 If the bullet is fired from a tracked Sprite or Pointer, or the
from
argument is set, this applies a horizontal offset from the launch position.offsetY
number <optional>
0 If the bullet is fired from a tracked Sprite or Pointer, or the
from
argument is set, this applies a vertical offset from the launch position.Returns:
The fired bullet, if a launch was successful, otherwise
null
.- Source - plugins/weapon/WeaponPlugin.js, line 817
-
fireAtPointer(pointer) → {Phaser.Bullet}
-
Fires a bullet at the given Pointer. The bullet will be launched from the
Weapon.fireFrom
position, or from a Tracked Sprite or Pointer, if you have one set.Parameters:
Name Type Argument Description pointer
Phaser.Pointer <optional>
The Pointer to fire the bullet towards.
Returns:
The fired bullet if successful, null otherwise.
- Source - plugins/weapon/WeaponPlugin.js, line 1092
-
fireAtSprite(sprite) → {Phaser.Bullet}
-
Fires a bullet at the given Sprite. The bullet will be launched from the
Weapon.fireFrom
position, or from a Tracked Sprite or Pointer, if you have one set.Parameters:
Name Type Argument Description sprite
Phaser.Sprite <optional>
The Sprite to fire the bullet towards.
Returns:
The fired bullet if successful, null otherwise.
- Source - plugins/weapon/WeaponPlugin.js, line 1108
-
fireAtXY(x, y) → {Phaser.Bullet}
-
Fires a bullet at the given coordinates. The bullet will be launched from the
Weapon.fireFrom
position, or from a Tracked Sprite or Pointer, if you have one set.Parameters:
Name Type Argument Description x
number <optional>
The x coordinate, in world space, to fire the bullet towards.
y
number <optional>
The y coordinate, in world space, to fire the bullet towards.
Returns:
The fired bullet if successful, null otherwise.
- Source - plugins/weapon/WeaponPlugin.js, line 1122
-
fireMany(positions, from) → {array}
-
Attempts to fire multiple bullets from the positions defined in the given array.
If you provide a
from
argument, or if there is a tracked Sprite or Pointer, then the positions are treated as offsets from the given objects position.If
from
is undefined, and there is no tracked object, then the bullets are fired from the given positions, as they exist in the world.Calling this method sets
Weapon.multiFire = true
.If there are not enough bullets available in the pool, and the pool cannot be extended, then this method may not fire from all of the given positions.
When the bullets are launched they have their texture and frame updated, as required. The velocity of the bullets are calculated based on Weapon properties like
bulletSpeed
.Parameters:
Name Type Argument Description positions
array An array of positions. Each position can be any Object, as long as it has public
x
andy
properties, such as Phaser.Point, { x: 0, y: 0 }, Phaser.Sprite, etc.from
Phaser.Sprite | Phaser.Point | Object | string <optional>
Optionally fires the bullets from the
x
andy
properties of this object, instead of anyWeapon.trackedSprite
ortrackedPointer
that is set.Returns:
array -An array containing all of the fired Phaser.Bullet objects, if a launch was successful, otherwise an empty array.
- Source - plugins/weapon/WeaponPlugin.js, line 736
-
fireOffset(offsetX, offsetY) → {Phaser.Bullet}
-
Attempts to fire a single Bullet from a tracked Sprite or Pointer, but applies an offset to the position first. This is the same as calling
Weapon.fire
and passing in the offset arguments.If there are no more bullets available in the pool, and the pool cannot be extended, then this method returns
null
. It will also returnnull
if not enough time has expired since the last time the Weapon was fired, as defined in theWeapon.fireRate
property.Otherwise the first available bullet is selected, launched, and returned.
When the bullet is launched it has its texture and frame updated, as required. The velocity of the bullet is calculated based on Weapon properties like
bulletSpeed
.If you wish to fire multiple bullets in a single game update, then set
Weapon.multiFire = true
and you can call this method as many times as you like, per loop. See alsoWeapon.fireMany
.Parameters:
Name Type Argument Default Description offsetX
number <optional>
0 The horizontal offset from the position of the tracked Sprite or Pointer, as set with
Weapon.trackSprite
.offsetY
number <optional>
0 The vertical offset from the position of the tracked Sprite or Pointer, as set with
Weapon.trackSprite
.Returns:
The fired bullet, if a launch was successful, otherwise
null
.- Source - plugins/weapon/WeaponPlugin.js, line 787
-
forEach(callback, callbackContext, args) → {Phaser.Weapon}
-
Call a function on each in-flight bullet in this Weapon.
See forEachExists for more details.
Parameters:
Name Type Argument Default Description callback
function The function that will be called for each applicable child. The child will be passed as the first argument.
callbackContext
object The context in which the function should be called (usually 'this').
args
any <optional>
<repeatable>
(none) Additional arguments to pass to the callback function, after the child item.
Returns:
This Weapon instance.
- Source - plugins/weapon/WeaponPlugin.js, line 516
-
killAll() → {Phaser.Weapon}
-
Calls
Bullet.kill
on every in-flight bullet in this Weapon. Also re-enables their physics bodies, should they have been disabled viapauseAll
.Returns:
This Weapon instance.
- Source - plugins/weapon/WeaponPlugin.js, line 567
-
pauseAll() → {Phaser.Weapon}
-
Sets
Body.enable
tofalse
on each bullet in this Weapon. This has the effect of stopping them in-flight should they be moving. It also stops them being able to be checked for collision.Returns:
This Weapon instance.
- Source - plugins/weapon/WeaponPlugin.js, line 535
-
<internal> postRender()
-
Internal update method, called by the PluginManager.
- Internal:
- This member is internal (protected) and may be modified or removed in the future.
- Source - plugins/weapon/WeaponPlugin.js, line 652
-
resetShots(newLimit) → {Phaser.Weapon}
-
Resets the
Weapon.shots
counter back to zero. This is used when you've setWeapon.fireLimit
, and have hit (or just wish to reset) your limit.Parameters:
Name Type Argument Description newLimit
integer <optional>
Optionally set a new
Weapon.fireLimit
.Returns:
This Weapon instance.
- Source - plugins/weapon/WeaponPlugin.js, line 584
-
resumeAll() → {Phaser.Weapon}
-
Sets
Body.enable
totrue
on each bullet in this Weapon. This has the effect of resuming their motion should they be in-flight. It also enables them for collision checks again.Returns:
This Weapon instance.
- Source - plugins/weapon/WeaponPlugin.js, line 551
-
setBulletBodyOffset(width, height, offsetX, offsetY) → {Phaser.Weapon}
-
You can modify the size of the physics Body the Bullets use to be any dimension you need. This allows you to make it smaller, or larger, than the parent Sprite. You can also control the x and y offset of the Body. This is the position of the Body relative to the top-left of the Sprite texture.
For example: If you have a Sprite with a texture that is 80x100 in size, and you want the physics body to be 32x32 pixels in the middle of the texture, you would do:
setSize(32 / Math.abs(this.scale.x), 32 / Math.abs(this.scale.y), 24, 34)
Where the first two parameters are the new Body size (32x32 pixels) relative to the Sprite's scale. 24 is the horizontal offset of the Body from the top-left of the Sprites texture, and 34 is the vertical offset.
Parameters:
Name Type Argument Description width
number The width of the Body.
height
number The height of the Body.
offsetX
number <optional>
The X offset of the Body from the top-left of the Sprites texture.
offsetY
number <optional>
The Y offset of the Body from the top-left of the Sprites texture.
Returns:
The Weapon Plugin.
- Source - plugins/weapon/WeaponPlugin.js, line 1137
-
setBulletFrames(min, max, cycle, random) → {Phaser.Weapon}
-
Sets the texture frames that the bullets can use when being launched.
This is intended for use when you've got numeric based frames, such as those loaded via a Sprite Sheet.
It works by calling
Phaser.ArrayUtils.numberArray
internally, using the min and max values provided. Then it sets the frame index to be zero.You can optionally set the cycle and random booleans, to allow bullets to cycle through the frames when they're fired, or pick one at random.
Parameters:
Name Type Argument Default Description min
integer The minimum value the frame can be. Usually zero.
max
integer The maximum value the frame can be.
cycle
boolean <optional>
true Should the bullet frames cycle as they are fired?
random
boolean <optional>
false Should the bullet frames be picked at random as they are fired?
Returns:
The Weapon Plugin.
- Source - plugins/weapon/WeaponPlugin.js, line 1178
-
trackPointer(pointer, offsetX, offsetY) → {Phaser.Weapon}
-
Sets this Weapon to track the given Pointer. When a Weapon tracks a Pointer it will automatically update its
fireFrom
value to match the Pointers position within the Game World, adjusting the coordinates based on the offset arguments.This allows you to lock a Weapon to a Pointer, so that bullets are always launched from its location.
Calling
trackPointer
will resetWeapon.trackedSprite
to null, should it have been set, as you can only track either a Pointer, or a Sprite, at once, but not both.Parameters:
Name Type Argument Default Description pointer
Phaser.Pointer <optional>
The Pointer to track the position of. Defaults to
Input.activePointer
if not specified.offsetX
integer <optional>
0 The horizontal offset from the Pointers position to be applied to the Weapon.
offsetY
integer <optional>
0 The vertical offset from the Pointers position to be applied to the Weapon.
Returns:
This Weapon instance.
- Source - plugins/weapon/WeaponPlugin.js, line 704
-
trackSprite(sprite, offsetX, offsetY, trackRotation) → {Phaser.Weapon}
-
Sets this Weapon to track the given Sprite, or any Object with a public
world
Point object. When a Weapon tracks a Sprite it will automatically update itsfireFrom
value to match the Sprites position within the Game World, adjusting the coordinates based on the offset arguments.This allows you to lock a Weapon to a Sprite, so that bullets are always launched from its location.
Calling
trackSprite
will resetWeapon.trackedPointer
to null, should it have been set, as you can only track either a Sprite, or a Pointer, at once, but not both.Parameters:
Name Type Argument Default Description sprite
Phaser.Sprite | Object The Sprite to track the position of.
offsetX
integer <optional>
0 The horizontal offset from the Sprites position to be applied to the Weapon.
offsetY
integer <optional>
0 The vertical offset from the Sprites position to be applied to the Weapon.
trackRotation
boolean <optional>
false Should the Weapon also track the Sprites rotation?
Returns:
This Weapon instance.
- Source - plugins/weapon/WeaponPlugin.js, line 671
-
<internal> update()
-
Internal update method, called by the PluginManager.
- Internal:
- This member is internal (protected) and may be modified or removed in the future.
- Source - plugins/weapon/WeaponPlugin.js, line 624


Software Development
Solutions Deployment
Requirements Definition
Coding & Scripting
Debugging & Troubleshooting
Testing & Documentation
Programming: C#, .NET, XML, SQL, Java, HTML5, CSS, Angular2, JavaScript, JQuery, Ionic 3
Software: Visual Studio (code), MS Office, Oracle, SQL Server, Firebase
Systems: Windows
I worked with an ERP system. My responsibility was integrate our system with government system through web services. I worked with solve client problems and sometimes I had to talk directly with them to understand what was the problem. I also worked with new features of the system, always thinking in improve the system performance and UX. If at Cetil I worked on Town Hall system, now I was working on the other side. I worked in one ERP system, and my module had to provide a WCF service to ERP send the invoices to us and we had to send all the invoices to the city halls and the government. At Senior I worked with .Net, WCF Services, SQL Server, Oracle, Java, Angular, HTML, CSS and JavaScript.
Responsabilities:
Analyze and develop new features for the framework
Support developers using the framework
Keep automated tests and documentation up to date
Lead a team of 4 developers on the development of new features
At Benner, I was hired only to work on an online ticket sales system. I was hired to contribute with the development of a new module to generate invoices when there were sales. When I finished this project, I was called to work at Senior Sistemas. At Benner I worked with .Net, WCF Services, SQL Server, Angular, HTML, CSS, jQuery and JavaScript.
Responsabilities:
Develop a new feature for the system
Keep automated tests and documentation up to date
In my first opportunity in IT area I was making a course of C# and I was selected with other five students to be hired. It was a great time to me, I learned a lot of things and was a great opportunity to work together with most experienced software developers. I worked in a system for town hall invoices control using .Net technology.
Responsabilities:
Develop new features for the system
Keep automated tests and documentation up to date
Fix and develop new features using native JavaScript and JQuery
Call: +64-27-2684611
Email: leoo.rossetti@gmail.com


Grove City High School (Grove City,OH) - | High School Sports
4665 Hoover Rd, Grove City OH, 43123-8621Map . High School (Conference). Location: Grove City High School Thu Dec 13 18:00:00 EST 2012 Event Page .
http://www.usatodayhss.com/school/grove-city-high-school-grove-city-oh
Treatment for Herniated or Bulging Discs
Water Powered Hydrogen Fuel Cell: Stan Meyers - The Full Story ...
Sep 2, 2011 . Stan Meyers Dune Buggy that ran on water. . T Henry Moray for pulling kilowatts out of the environment and Ed Gray for daring to have . Meyer's cell, developed at the inventor's home in Grove City, Ohio, produced far more .
http://truedemocracyparty.net/2011/09/water-powered-hydrogen-fuel-cell-stan-meyers-the-full-story/
Ed Myers profiles | LinkedIn
View the profiles of professionals named Ed Myers on LinkedIn. . Past: Professor at Harding University, Professor at Ohio Valley University; Education: Drew . at Starr Companies; Demographic info: Greater New York City Area | Insurance . at Elk Grove Baptist Church, Group Discussion Facilitator at Myers Place Media, .
http://us.linkedin.com/pub/dir/Ed/Myers
edwin meyers grove city ohio Herniated or Bulging Discs
Elks.org :: Past Grand Exalted Rulers
Lodge Locator · Register; Member Login. Username: Password: .
http://www.elks.org/history/pgers.cfm
Nuisance Wildlife Trappers - Ohio Department of Natural Resources
3, Ashtabula, Jefferson, Nathan Meyer,<PHONE_NUMBER>. 3, Ashtabula, N. . 1, Franklin, Grove City, Dennis Roberts,<PHONE_NUMBER>. 1, Franklin, Groveport .
http://www.dnr.state.oh.us/LinkClick.aspx?link=23887&tabid=5674
BMA Boards, Committees, Councils, and Sub-committees
809 Lombard Road, Plain City, OH 43064. Phone: (740) 857- . Email: ed.meyers @juno.com. Central Regional . 370 Suedberg Rd., Pine Grove, PA 17963 .
http://www.biblicalmennonite.com/bma-boards.html
Official Impairment Listing for Spinal Disorders
The Birth of New Technology - Open | Source | Energy
"Meets All Energy Needs ". WATEWELCELL Stanley A. Meyer, Inventor. 000. 3792 Broadway. Grove City, Ohio 43123. 1-614-871-4173. Jesus cnnm swan Fax : .
http://open-source-energy.org/rwg42985/russ/Patents/S.Meyer-The%20Birth%20of%20New%20Technology.pdf
- apply cover letter online resume (narrowing of the spine)
Stan Meyer's Dune Buggy
Feb 2, 2007 . RWG Research has more Stan Meyer FREE information . aired news cast, from his home town of Grove City , Ohio that you are not to view. . out of the environment and Ed Gray for daring to have a power tube with an output .
http://www.waterpoweredcar.com/stanmeyer.html1970's - Wrestling USA Magazine
Everett Gomez Oklahoma City, OK . Marvin Rath, Turtle Lake, N.D.; Rick Kornell , Maple Heights, Ohio; Les Carman, . Ed Maisey, Williston, North Dakota; Randy Bruins, Watford City, North Dakota . Chuck Davis Grove City HS, Grove City, OH . Don Meyer Reedsburg HS, Reedsburg, WI; HONORABLE MENTION ALL- .
http://www.wrestlingusa.com/003%20wusa%20web%20root/wusahalloffame/70hsallamerican.html
Clermont County, Ohio - Wikipedia, the free encyclopedia
Largest city, Milford . Clermont County is a county located in the state of Ohio, United States, just east . In March 2012, the Clermont County Commissioners are Republicans Bob Proud, Ed Humphrey, and . 65th Ohio House district features Steve Myers of Milford, the Democratic nominee, . Cherry Grove · Day Heights .
http://en.wikipedia.org/wiki/Clermont_County,_Ohio
Medical-Vocational Allowance for Herniated Disc
Walmart
Provides a wide array of electronics, apparel, baby, sports, toys and fitness. Includes a store finder and blog.
http://www.walmart.com/
The car that ran on water | The Columbus Dispatch
Jul 8, 2007 . Stanley Allen Meyer, his brother and two Belgian investors raised glasses in the Grove City Cracker Barrel on March 20, 1998. Meyer said his .
http://www.dispatch.com/live/content/local_news/stories/2007/07/08/hydroman.ART_ART_07-08-07_A1_4V77MOK.html
Ohio District Maps
Ohio State Board of Education Districts. Ohio Secretary of . Ohio House of Representatives Districts . . by Grove City) . ed by Ward 1 in the City of Hamilton) .
http://www.ohiocathconf.org/l/eDistMaps.pdf
Appealing a Denial of Benefits
COMPREHENSIVE PLAN - Parks and Recreation - Grove City, Ohio
4035 Broadway, Grove City, OH 43123.<PHONE_NUMBER> . Bill Myers, Co- Secretary. Jeff Buskirk . Ed Merritt, Recreation Superintendent. Caitlin Sampsel .
http://parks.grovecityohio.gov/editor/files/departments/parks/compPlan/compPlanWeb.pdf
Stanley Meyer - So you think we have an energy problem
Sep 20, 2006 . [Handbook of Chemistry & Physics, 68th ed., CRC . Inventors: Meyer; Stanley A . (3792 Broadway, Grove City, OH 43123). Appl. No.: 081859 .
http://www.byronwine.com/files/MEYER%20PAGE.pdf


We are looking for an Android Senior Developer who possesses a passion for pushing mobile technologies to the limits and will work with our team of talented engineers to design and build the next generation of our mobile applications.
Have you handled end to end android development with release to play store? Do you have apps with more than a few thousand downloads? Are you an expert in Material Design and crafting excellent UX experience? Do you know how to integrate with API's, cloud databases and services and work seamlessly with other developers using GitHub?
Are you passionate about technology & development and like to work hard in an international team who following lean and agile principles? Would you like to work in a fast-paced startup with growth opportunities only limited by your talent?
If yes, come talk to us!
We are looking for a Senior Developer who possesses a passion for pushing web technologies to the limits and will work with our team of talented engineers to design and build the next generation of our web/mobile applications.
Have you handled end to end web development owning a vertical stack from database to UI? Have you developed applications scaling with thousand of users? Are you an expert in writing optimized code with sound algorithm logic? Do you know how to create/work with API's, cloud databases and services and work seamlessly with mobile developers using GitHub?
Depending on your experience, you will be the team leader managing the complete development team of mobile and web engineers.
Are you passionate about technology & development and like to work hard in an international team who following lean and agile principles? Would you like to work in a fast-paced startup with growth opportunities only limited by your talent?
If yes, come talk to us!
We are looking for a Senior Developer who possesses a passion for pushing web frontend technologies to the limits and will work with our team of talented engineers to design and build the next generation of our web/mobile applications.
Have you handled end to end web front-end development with the latest technologies HTML5, CSS, Javascript? Have you developed applications scaling with thousand of users? Are you an expert in UI Design and crafting excellent UX experience? Do you know how to create/work with API's, cloud databases and services and work seamlessly with other developers using GitHub?
Are you passionate about technology & development and like to work hard in an international team who following lean and agile principles? Would you like to work in a fast-paced startup with growth opportunities only limited by your talent?
If yes, come talk to us!


---
layout: post
title: Tinrocket.com | John Balestrieri
date: '2013-07-27T22:42:00+02:00'
categories:
- Apps & Software
picture_url: https://film-Storyboards.tumblr.com/post/56659720667/tinrocketcom-john-balestrieri
---
Tinrocket.com | John Balestrieri
A lot of interesting graphic apps and cool code projects under development here (probably not the intended goal, but some of these might put a few more illustrators out of business at some point).


TypesType Systems
Our next topic, a large one, is type systems — static program
analyses that classify expressions according to the "shapes" of
their results. We'll begin with a typed version of a very simple
language with just booleans and numbers, to introduce the basic
ideas of types, typing rules, and the fundamental theorems about
type systems: type preservation and progress. Then we'll move
on to the simply typed lambda-calculus, which lives at the core
of every modern functional programming language (including
Coq).
Before we start, let's spend a little time learning to use
some of Coq's more powerful automation features...
The auto tactic solves goals that are solvable by any combination of
The eauto tactic works just like auto, except that it uses
eapply instead of apply.
Using auto is always "safe" in the sense that it will never fail
and will never change the proof state: either it completely solves
the current goal, or it does nothing.
Here is a contrived example:
More Automation
The auto and eauto Tactics
- intros,
- apply (with a local hypothesis, by default), and
- reflexivity.
Lemma auto_example_1 : ∀ P Q R S T U : Prop,
(P → Q) →
(P → R) →
(T → R) →
(S → T → U) →
((P→Q) → (P→S)) →
T →
P →
U.
Proof. auto. Qed.
When searching for potential proofs of the current goal, auto
and eauto consider the hypotheses in the current context
together with a hint database of other lemmas and constructors.
Some of the lemmas and constructors we've already seen — e.g.,
conj, or_introl, and or_intror — are installed in this hint
database by default.
We can extend the hint database just for the purposes of one
application of auto or eauto by writing auto using ....
E.g., if conj, or_introl, and or_intror had not already
been in the hint database, we could have done this instead:
Lemma auto_example_2a : ∀ P Q R : Prop,
Q →
(Q → R) →
P ∨ (Q ∧ R).
Proof.
auto using conj, or_introl, or_intror. Qed.
Of course, in any given development there will also be some of our
own specific constructors and lemmas that are used very often in
proofs. We can add these to the global hint database by writing
It is also sometimes necessary to add
Here are some Hints we will find useful.
Hint Resolve l.
at the top level, where l is a top-level lemma theorem or a
constructor of an inductively defined proposition (i.e., anything
whose type is an implication). As a shorthand, we can write
Hint Constructors c.
to tell Coq to do a Hint Resolve for all of the constructors
from the inductive definition of c.
Hint Unfold d.
where d is a defined symbol, so that auto knows to expand
uses of d and enable further possibilities for applying
lemmas that it knows about.
Warning: Just as with Coq's other automation facilities, it is
easy to overuse auto and eauto and wind up with proofs that
are impossible to understand later!
Also, overuse of eauto can make proof scripts very slow. Get in
the habit of using auto most of the time and eauto only when
necessary.
For much more detailed information about using auto and eauto,
see the chapter UseAuto.v.
If you start a proof by saying Proof with (tactic) instead of
just Proof, then writing ... instead of . after a tactic in
the body of the proof will try to solve all generated subgoals
with tactic (and fail if this doesn't work).
One common use of this facility is "Proof with auto" (or
eauto). We'll see many examples of this later in the file.
Here's another nice automation feature: it often arises that the
context contains a contradictory assumption and we want to use
inversion on it to solve the goal. We'd like to be able to say
to Coq, "find a contradictory assumption and invert it" without
giving its name explicitly.
Doing solve by inversion will find a hypothesis that can be
inverted to solve the goal, if there is one. The tactics solve
by inversion 2 and solve by inversion 3 are slightly fancier
versions which will perform two or three inversions in a row, if
necessary, to solve the goal.
(These tactics are not actually built into Coq — their
definitions are in Sflib.v.)
Caution: Overuse of solve by inversion can lead to slow proof
scripts.
If t is a tactic, then try solve [t] is a tactic that
More generally, try solve [t1 | t2 | ...] will try to solve the
goal by using t1, t2, etc. If none of them succeeds in
completely solving the goal, then try solve [t1 | t2 | ...] does
nothing.
The fact that it does nothing when it doesn't completely succeed
in solving the goal means that there is no harm in using try
solve T in situations where T might actually make no sense. In
particular, if we put it after a ; it will solve as many
subgoals as it can and leave the rest for us to solve by other
methods. It will not leave any of the subgoals in a partially
solved state.
This handy tactic replaces a goal of the form f x1 x2 ... xn = f
y1 y2 ... yn, where f is some function, with the subgoals x1 =
y1, x2 = y2,...,xn = yn. It is useful for avoiding explicit
rewriting steps, and often the generated subgoals can be quickly
cleared by auto.
When experimenting with definitions of programming languages in
Coq, we often want to see what a particular concrete term steps
to — i.e., we want to find proofs for goals of the form t ⇒*
t', where t is a completely concrete term and t' is unknown.
These proofs are simple but repetitive to do by hand. Consider for
example reducing an arithmetic expression using the small-step
relation astep defined in the previous chapter:
The Proof with Tactic
The solve by inversion Tactic
The try solve Tactic
- if t solves the goal, behaves just like t, or
- if t cannot completely solve the goal, does nothing.
The f_equal Tactic
The normalize Tactic
Definition astep_many st := refl_step_closure (astep st).
Notation " t '/' st '⇒a*' t' " := (astep_many st t t')
(at level 40, st at level 39).
Example astep_example1 :
(APlus (ANum 3) (AMult (ANum 3) (ANum 4))) / empty_state
⇒a* (ANum 15).
Proof.
apply rsc_step with (APlus (ANum 3) (ANum 12)).
apply AS_Plus2.
apply av_num.
apply AS_Mult.
apply rsc_step with (ANum 15).
apply AS_Plus.
apply rsc_refl.
Qed.
We repeatedly applied rsc_step until we got to a normal
form. The proofs that the intermediate steps are possible are
simple enough that auto, with appropriate hints, can solve
them.
Hint Constructors astep aval.
Example astep_example1' :
(APlus (ANum 3) (AMult (ANum 3) (ANum 4))) / empty_state
⇒a* (ANum 15).
Proof.
eapply rsc_step. auto. simpl.
eapply rsc_step. auto. simpl.
apply rsc_refl.
Qed.
The following custom Tactic Notation definition captures this
pattern. In addition, before each rsc_step we print out the
current goal, so that the user can follow how the term is being
evaluated.
Tactic Notation "print_goal" := match goal with ⊢ ?x => idtac x end.
Tactic Notation "normalize" :=
repeat (print_goal; eapply rsc_step ;
[ (eauto 10; fail) | (instantiate; simpl)]);
apply rsc_refl.
Example astep_example1'' :
(APlus (ANum 3) (AMult (ANum 3) (ANum 4))) / empty_state
⇒a* (ANum 15).
Proof.
normalize.
(* At this point in the proof script, the Coq response shows
a trace of how the expression evaluated. *)
Qed.
Finally, this is also useful as a simple way to calculate what the normal
form of a term is, by proving a goal with an existential variable in it.
Example astep_example1''' : ∃ e',
(APlus (ANum 3) (AMult (ANum 3) (ANum 4))) / empty_state
⇒a* e'.
Proof.
eapply ex_intro. normalize.
Qed.
Typed Arithmetic Expressions
Syntax
Inductive tm : Type :=
| tm_true : tm
| tm_false : tm
| tm_if : tm → tm → tm → tm
| tm_zero : tm
| tm_succ : tm → tm
| tm_pred : tm → tm
| tm_iszero : tm → tm.
Inductive bvalue : tm → Prop :=
| bv_true : bvalue tm_true
| bv_false : bvalue tm_false.
Inductive nvalue : tm → Prop :=
| nv_zero : nvalue tm_zero
| nv_succ : ∀ t, nvalue t → nvalue (tm_succ t).
Definition value (t:tm) := bvalue t ∨ nvalue t.
Hint Constructors bvalue nvalue.
Hint Unfold value.
Reserved Notation "t1 '⇒' t2" (at level 40).
Inductive step : tm → tm → Prop :=
| ST_IfTrue : ∀ t1 t2,
(tm_if tm_true t1 t2) ⇒ t1
| ST_IfFalse : ∀ t1 t2,
(tm_if tm_false t1 t2) ⇒ t2
| ST_If : ∀ t1 t1' t2 t3,
t1 ⇒ t1' →
(tm_if t1 t2 t3) ⇒ (tm_if t1' t2 t3)
| ST_Succ : ∀ t1 t1',
t1 ⇒ t1' →
(tm_succ t1) ⇒ (tm_succ t1')
| ST_PredZero :
(tm_pred tm_zero) ⇒ tm_zero
| ST_PredSucc : ∀ t1,
nvalue t1 →
(tm_pred (tm_succ t1)) ⇒ t1
| ST_Pred : ∀ t1 t1',
t1 ⇒ t1' →
(tm_pred t1) ⇒ (tm_pred t1')
| ST_IszeroZero :
(tm_iszero tm_zero) ⇒ tm_true
| ST_IszeroSucc : ∀ t1,
nvalue t1 →
(tm_iszero (tm_succ t1)) ⇒ tm_false
| ST_Iszero : ∀ t1 t1',
t1 ⇒ t1' →
(tm_iszero t1) ⇒ (tm_iszero t1')
where "t1 '⇒' t2" := (step t1 t2).
Tactic Notation "step_cases" tactic(first) ident(c) :=
first;
[ Case_aux c "ST_IfTrue" | Case_aux c "ST_IfFalse" | Case_aux c "ST_If"
| Case_aux c "ST_Succ" | Case_aux c "ST_PredZero"
| Case_aux c "ST_PredSucc" | Case_aux c "ST_Pred"
| Case_aux c "ST_IszeroZero" | Case_aux c "ST_IszeroSucc"
| Case_aux c "ST_Iszero" ].
Hint Constructors step.
Notice that the step relation doesn't care about whether
expressions make global sense — it just checks that the operation
in the next reduction step is being applied to the right kinds
of operands. For example, the term tm_succ tm_true cannot take
a step, but the almost-as-obviously-nonsensical term
The first interesting thing about the step relation in this
language is that the strong progress theorem from the Smallstep
chapter fails! That is, there are terms that are normal
forms (they can't take a step) but not values (because we have not
included them in our definition of possible "results of
evaluation"). Such terms are stuck.
tm_succ (tm_if tm_true tm_true tm_true)
can.
Normal Forms and Values
Notation step_normal_form := (normal_form step).
Definition stuck (t:tm) : Prop :=
step_normal_form t ∧ ~ value t.
Hint Unfold stuck.
☐
However, although values and normal forms are not the same in this
language, the former set is included in the latter. This is
important because it shows we did not accidentally define things
so that some value could still take a step.
Exercise: 3 stars, optional (value_is_nf)
Hint: You will reach a point in this proof where you need to use an induction to reason about a term that is known to be a numeric value. This induction can be performed either over the term itself or over the evidence that it is a numeric value. The proof goes through in either case, but you will find that one way is quite a bit shorter than the other. For the sake of the exercise, try to complete the proof both ways.
☐
Exercise: 3 stars, optional (step_deterministic)
Using value_is_nf, we can show that the step relation is also deterministic...
☐
The next critical observation about this language is that,
although there are stuck terms, they are all "nonsensical", mixing
booleans and numbers in a way that we don't even want to have a
meaning. We can easily exclude such ill-typed terms by defining a
typing relation that relates terms to the types (either numeric
or boolean) of their final results.
Typing
The typing relation:
In informal notation, the typing relation is often written ⊢ t :
T, pronounced "t has type T." The ⊢ symbol is called a
"turnstile". (Below, we're going to see richer typing relations
where an additional "context" argument is written to the left of
the turnstile. Here, the context is always empty.)
| (T_True) | |
| ⊢ true : Bool |
| (T_False) | |
| ⊢ false : Bool |
| ⊢ t1 : Bool ⊢ t2 : T ⊢ t3 : T | (T_If) |
| ⊢ if t1 then t2 else t3 : T |
| (T_Zero) | |
| ⊢ 0 : Nat |
| ⊢ t1 : Nat | (T_Succ) |
| ⊢ succ t1 : Nat |
| ⊢ t1 : Nat | (T_Pred) |
| ⊢ pred t1 : Nat |
| ⊢ t1 : Nat | (T_IsZero) |
| ⊢ iszero t1 : Bool |
Inductive has_type : tm → ty → Prop :=
| T_True :
has_type tm_true ty_Bool
| T_False :
has_type tm_false ty_Bool
| T_If : ∀ t1 t2 t3 T,
has_type t1 ty_Bool →
has_type t2 T →
has_type t3 T →
has_type (tm_if t1 t2 t3) T
| T_Zero :
has_type tm_zero ty_Nat
| T_Succ : ∀ t1,
has_type t1 ty_Nat →
has_type (tm_succ t1) ty_Nat
| T_Pred : ∀ t1,
has_type t1 ty_Nat →
has_type (tm_pred t1) ty_Nat
| T_Iszero : ∀ t1,
has_type t1 ty_Nat →
has_type (tm_iszero t1) ty_Bool.
Tactic Notation "has_type_cases" tactic(first) ident(c) :=
first;
[ Case_aux c "T_True" | Case_aux c "T_False" | Case_aux c "T_If"
| Case_aux c "T_Zero" | Case_aux c "T_Succ" | Case_aux c "T_Pred"
| Case_aux c "T_Iszero" ].
Hint Constructors has_type.
Examples
Example has_type_1 :
has_type (tm_if tm_false tm_zero (tm_succ tm_zero)) ty_Nat.
Proof.
apply T_If.
apply T_False.
apply T_Zero.
apply T_Succ.
apply T_Zero.
Qed.
(Since we've included all the constructors of the typing relation
in the hint database, the auto tactic can actually find this
proof automatically.)
Example has_type_not :
~ has_type (tm_if tm_false tm_zero tm_true) ty_Bool.
Proof.
intros Contra. solve by inversion 2. Qed.
Example succ_hastype_nat__hastype_nat : ∀ t,
has_type (tm_succ t) ty_Nat →
has_type t ty_Nat.
Proof.
(* FILL IN HERE *) Admitted.
has_type (tm_succ t) ty_Nat →
has_type t ty_Nat.
Proof.
(* FILL IN HERE *) Admitted.
☐
The typing relation enjoys two critical properties. The first is
that well-typed normal forms are values (i.e., not stuck).
Theorem: If ⊢ t : T, then either t is a value or else
t ⇒ t' for some t'.
Proof: By induction on a derivation of ⊢ t : T.
(* FILL IN HERE *)
☐
Progress
Exercise: 3 stars, recommended (finish_progress_informal)
Complete the following proof:- If the last rule in the derivation is T_If, then t = if t1
then t2 else t3, with ⊢ t1 : Bool, ⊢ t2 : T and ⊢ t3
: T. By the IH, either t1 is a value or else t1 can step
to some t1'.
- If t1 is a value, then it is either an nvalue or a
bvalue. But it cannot be an nvalue, because we know
⊢ t1 : Bool and there are no rules assigning type
Bool to any term that could be an nvalue. So t1
is a bvalue — i.e., it is either true or false.
If t1 = true, then t steps to t2 by ST_IfTrue,
while if t1 = false, then t steps to t3 by
ST_IfFalse. Either way, t can step, which is what
we wanted to show.
- If t1 itself can take a step, then, by ST_If, so can t.
- If t1 is a value, then it is either an nvalue or a
bvalue. But it cannot be an nvalue, because we know
⊢ t1 : Bool and there are no rules assigning type
Bool to any term that could be an nvalue. So t1
is a bvalue — i.e., it is either true or false.
If t1 = true, then t steps to t2 by ST_IfTrue,
while if t1 = false, then t steps to t3 by
ST_IfFalse. Either way, t can step, which is what
we wanted to show.
☐
Exercise: 3 stars (finish_progress)
Theorem progress : ∀ t T,
has_type t T →
value t ∨ ∃ t', t ⇒ t'.
Proof with auto.
intros t T HT.
has_type_cases (induction HT) Case...
(* The cases that were obviously values, like T_True and
T_False, were eliminated immediately by auto *)
Case "T_If".
right. destruct IHHT1.
SCase "t1 is a value". destruct H.
SSCase "t1 is a bvalue". destruct H.
SSSCase "t1 is tm_true".
∃ t2...
SSSCase "t1 is tm_false".
∃ t3...
SSCase "t1 is an nvalue".
solve by inversion 2. (* on H and HT1 *)
SCase "t1 can take a step".
destruct H as [t1' H1].
∃ (tm_if t1' t2 t3)...
(* FILL IN HERE *) Admitted.
has_type t T →
value t ∨ ∃ t', t ⇒ t'.
Proof with auto.
intros t T HT.
has_type_cases (induction HT) Case...
(* The cases that were obviously values, like T_True and
T_False, were eliminated immediately by auto *)
Case "T_If".
right. destruct IHHT1.
SCase "t1 is a value". destruct H.
SSCase "t1 is a bvalue". destruct H.
SSSCase "t1 is tm_true".
∃ t2...
SSSCase "t1 is tm_false".
∃ t3...
SSCase "t1 is an nvalue".
solve by inversion 2. (* on H and HT1 *)
SCase "t1 can take a step".
destruct H as [t1' H1].
∃ (tm_if t1' t2 t3)...
(* FILL IN HERE *) Admitted.
☐
This is more interesting than the strong progress theorem that we
saw in the Smallstep chapter, where all normal forms were
values. Here, a term can be stuck, but only if it is ill
typed.
☐
The second critical property of typing is that, when a well-typed
term takes a step, the result is also a well-typed term.
This theorem is often called the subject reduction property,
because it tells us what happens when the "subject" of the typing
relation is reduced. This terminology comes from thinking of
typing statements as sentences, where the term is the subject and
the type is the predicate.
Theorem: If ⊢ t : T and t ⇒ t', then ⊢ t' : T.
Proof: By induction on a derivation of ⊢ t : T.
(* FILL IN HERE *)
☐
Exercise: 1 star (step_review)
Quick review. Answer true or false. (As usual, no need to hand these in.)- In this language, every well-typed normal form is a value.
- Every value is a normal form.
- The single-step evaluation relation is
a partial function.
- The single-step evaluation relation is a total function.
Type Preservation
Exercise: 3 stars, recommended (finish_preservation_informal)
Complete the following proof:- If the last rule in the derivation is T_If, then t = if t1
then t2 else t3, with ⊢ t1 : Bool, ⊢ t2 : T and ⊢ t3
: T.
Inspecting the rules for the small-step reduction relation and remembering that t has the form if ..., we see that the only ones that could have been used to prove t ⇒ t' are ST_IfTrue, ST_IfFalse, or ST_If.
- If the last rule was ST_IfTrue, then t' = t2. But we
know that ⊢ t2 : T, so we are done.
- If the last rule was ST_IfFalse, then t' = t3. But we
know that ⊢ t3 : T, so we are done.
- If the last rule was ST_If, then t' = if t1' then t2 else t3, where t1 ⇒ t1'. We know ⊢ t1 : Bool so, by the IH, ⊢ t1' : Bool. The T_If rule then gives us ⊢ if t1' then t2 else t3 : T, as required.
- If the last rule was ST_IfTrue, then t' = t2. But we
know that ⊢ t2 : T, so we are done.
☐
Exercise: 2 stars (finish_preservation)
Theorem preservation : ∀ t t' T,
has_type t T →
t ⇒ t' →
has_type t' T.
Proof with auto.
intros t t' T HT HE.
generalize dependent t'.
has_type_cases (induction HT) Case;
(* every case needs to introduce a couple of things *)
intros t' HE;
(* and we can deal with several impossible
cases all at once *)
try (solve by inversion).
Case "T_If". inversion HE; subst.
SCase "ST_IFTrue". assumption.
SCase "ST_IfFalse". assumption.
SCase "ST_If". apply T_If; try assumption.
apply IHHT1; assumption.
(* FILL IN HERE *) Admitted.
has_type t T →
t ⇒ t' →
has_type t' T.
Proof with auto.
intros t t' T HT HE.
generalize dependent t'.
has_type_cases (induction HT) Case;
(* every case needs to introduce a couple of things *)
intros t' HE;
(* and we can deal with several impossible
cases all at once *)
try (solve by inversion).
Case "T_If". inversion HE; subst.
SCase "ST_IFTrue". assumption.
SCase "ST_IfFalse". assumption.
SCase "ST_If". apply T_If; try assumption.
apply IHHT1; assumption.
(* FILL IN HERE *) Admitted.
☐
Exercise: 3 stars (preservation_alternate_proof)
Now prove the same property again by induction on the evaluation derivation instead of on the typing derivation. Begin by carefully reading and thinking about the first few lines of the above proof to make sure you understand what each one is doing. The set-up for this proof is similar, but not exactly the same.Theorem preservation' : ∀ t t' T,
has_type t T →
t ⇒ t' →
has_type t' T.
Proof with eauto.
(* FILL IN HERE *) Admitted.
☐
Putting progress and preservation together, we can see that a
well-typed term can never reach a stuck state.
Type Soundness
Definition stepmany := (refl_step_closure step).
Notation "t1 '⇒*' t2" := (stepmany t1 t2) (at level 40).
Corollary soundness : ∀ t t' T,
has_type t T →
t ⇒* t' →
~(stuck t').
Proof.
intros t t' T HT P. induction P; intros [R S].
destruct (progress x T HT); auto.
apply IHP. apply (preservation x y T HT H).
unfold stuck. split; auto. Qed.
Indeed, in the present — extremely simple — language,
every well-typed term can be reduced to a normal form: this is the
normalization property. (The proof is straightforward, though
somewhat tedious.) In richer languages, this property often fails,
though there are some interesting languages (such as Coq's
Fixpoint language, and the simply typed lambda-calculus, which
we'll be looking at next) where all well-typed terms can be
reduced to normal forms.
(* FILL IN HERE *)
☐
☐
☐
☐
☐
☐
☐
☐
☐
(* FILL IN HERE *)
☐
(* FILL IN HERE *)
☐
Additional Exercises
Exercise: 2 stars, recommended (subject_expansion)
Having seen the subject reduction property, it is reasonable to wonder whether the opposity property — subject expansion — also holds. That is, is it always the case that, if t ⇒ t' and has_type t' T, then has_type t T? If so, prove it. If not, give a counter-example.☐
Exercise: 2 stars (variation1)
Suppose we add the following two new rules to the evaluation relation:
| ST_PredTrue :
(tm_pred tm_true) ⇒ (tm_pred tm_false)
| ST_PredFalse :
(tm_pred tm_false) ⇒ (tm_pred tm_true)
Which of the following properties remain true in the presence
of these rules? For each one, write either "remains true" or
else "becomes false." If a property becomes false, give a
counterexample.
(tm_pred tm_true) ⇒ (tm_pred tm_false)
| ST_PredFalse :
(tm_pred tm_false) ⇒ (tm_pred tm_true)
- Determinacy of step
- Normalization of step for well-typed terms
- Progress
- Preservation
Exercise: 2 stars (variation2)
Suppose, instead, that we add this new rule to the typing relation:
| T_IfFunny : ∀ t2 t3,
has_type t2 ty_Nat →
has_type (tm_if tm_true t2 t3) ty_Nat
Which of the following properties remain true in the presence of
this rule? (Answer in the same style as above.)
has_type t2 ty_Nat →
has_type (tm_if tm_true t2 t3) ty_Nat
- Determinacy of step
- Normalization of step for well-typed terms
- Progress
- Preservation
Exercise: 2 stars (variation3)
Suppose, instead, that we add this new rule to the typing relation:
| T_SuccBool : ∀ t,
has_type t ty_Bool →
has_type (tm_succ t) ty_Bool
Which of the following properties remain true in the presence of
this rule? (Answer in the same style as above.)
has_type t ty_Bool →
has_type (tm_succ t) ty_Bool
- Determinacy of step
- Normalization of step for well-typed terms
- Progress
- Preservation
Exercise: 2 stars (variation4)
Suppose, instead, that we add this new rule to the step relation:
| ST_Funny1 : ∀ t2 t3,
(tm_if tm_true t2 t3) ⇒ t3
Which of the above properties become false in the presence of
this rule? For each one that does, give a counter-example.
(tm_if tm_true t2 t3) ⇒ t3
Exercise: 2 stars (variation5)
Suppose instead that we add this rule:
| ST_Funny2 : ∀ t1 t2 t2' t3,
t2 ⇒ t2' →
(tm_if t1 t2 t3) ⇒ (tm_if t1 t2' t3)
Which of the above properties become false in the presence of
this rule? For each one that does, give a counter-example.
t2 ⇒ t2' →
(tm_if t1 t2 t3) ⇒ (tm_if t1 t2' t3)
Exercise: 2 stars (variation6)
Suppose instead that we add this rule:
| ST_Funny3 :
(tm_pred tm_false) ⇒ (tm_pred (tm_pred tm_false))
Which of the above properties become false in the presence of
this rule? For each one that does, give a counter-example.
(tm_pred tm_false) ⇒ (tm_pred (tm_pred tm_false))
Exercise: 2 stars (variation7)
Suppose instead that we add this rule:
| T_Funny4 :
has_type tm_zero ty_Bool
Which of the above properties become false in the presence of
this rule? For each one that does, give a counter-example.
has_type tm_zero ty_Bool
Exercise: 2 stars (variation8)
Suppose instead that we add this rule:
| T_Funny5 :
has_type (tm_pred tm_zero) ty_Bool
Which of the above properties become false in the presence of
this rule? For each one that does, give a counter-example.
has_type (tm_pred tm_zero) ty_Bool
Exercise: 3 stars, optional (more_variations)
Make up some exercises of your own along the same lines as the ones above. Try to find ways of selectively breaking properties — i.e., ways of changing the definitions that break just one of the properties and leave the others alone. ☐Exercise: 1 star (remove_predzero)
The evaluation rule E_PredZero is a bit counter-intuitive: we might feel that it makes more sense for the predecessor of zero to be undefined, rather than being defined to be zero. Can we achieve this simply by removing the rule from the definition of step?☐
Exercise: 4 stars, optional (prog_pres_bigstep)
Suppose our evaluation relation is defined in the big-step style. What are the appropriate analogs of the progress and preservation properties?☐