text:
# Portfolio Wind Production

## Problem Description¶

In these solution template we will describe forecasting of aggregated production of more wind farms. There are two possible cases, in this solution template we will describe the second scenario. 1. Production of each individual wind farm is available and production of the whole portfolio is sum of individual productions. In this case individual model and forecast can be generated for each wind farm (see Single Asset Wind Forecasting) and then summed up to obtain production forecast of whole portfolio. With this approach is easy to consider scheduled maintenance of individual wind farms or adapt to change in portfolio size because only active wind farms will be summed up. 2. Only production of the whole portfolio is available. In this case is model generated for whole portfolio considering location of individual wind farms and meteorological situation there. In this solution template we will describe this scenario. Typical scenarios in wind production forecasting are from few hours ahead to few days ahead (usually up to 36h or 48h ahead). Data sampling rate is mostly 15 minutes, 30 minutes or hourly. Typical metrics used to evaluate how good is the prediction are MAE and RMSE. To evaluate error in percent’s nMAE, nRMSE, rMAE or rRMSE are used.

## Data Recommendation Template¶

Essential for wind production forecasting is to have good wind speed forecast. The most important are wind speed and wind direction forecasts at hub high of individual wind turbines. The key is to find an appropriate GPS coordinates that represent portfolio the best. This task doesn’t have an exact solution. We recommend taking into account locations of individual wind farms and their installed capacities. Our best practice in finding GPS coordinates for meteo data is to do clustering on locations of wind farms weighted by their installed capacity. We use centroids of these clusters as our GPS coordinates for meteo data. However, number of clusters that get best results is still the question. Best practice is to use historical actuals of meteo predictors for model building and meteorological forecasts for out-of-sample validation.
Other meteo predictors as wind gusts, temperature, irradiation and pressure may improve models. They are recommended only for further fine-tuning. In general, the typical situation is that the portfolio is changing. Currently our best practice is to choose for training last stable part.

## TIM Setup¶

TIM requires no setup of TIMs mathematical internals and works well in business user mode. All that is required from a user is to let TIM know a forecasting routine and desired prediction horizon. TIM can automatically learn that there is no weekly pattern, in some cases, however, (e.g. short datasets) it can be difficult to learn this and therefore we recommend switching off the weekdays dictionary. If target availability is higher than 6 hours, target offsets do not improve model, we may switch them off. Model building will be faster and accuracy will be the same.

## Demo example¶

### Data description¶

A prepared dataset for this problem, along with a prepared configuration YAML-file, can be downloaded here. Data used in this example are from 2018-01-01 to 2019-08-15.

### Target¶

Data used in this example are from the UK. Production data are available and can be downloaded from the web page https://www2.bmreports.com/bmrs/?q=generation/windforcast/out-turn. Sum of production of all wind farms in the UK is our target. It is the second column in CSV file, right after column with timestamps. In this case name of the target is Quantity. Data are in half-hourly granularity.

### Predictor candidates¶

We will use 10 GPS coordinates across the UK. As predictors will be used wind speeds at heights 100m, 120m and wind direction at high 100m for each of 10 given GPS coordinates. In this demo we are using historical actuals for model building and meteo forecasts for out-of-sample forecasting. In this example, we will use two csv files, one for TIM Studio and other for connector.

1.) CSV file for TIM Studio contains merged historical actuals with forecasts of meteo predictors. Predictors used for model building are historical actuals (up to timestamp 2019-06-30 23:30:00) and for out-of-sample validation are meteo forecasts (from timestamp 2019-07-01 00:00:00). (File location: TIM_Studio_data/data.csv)

2.) Since connector allows you to specify columns with forecasts. For connector actuals and forecasts are in separate columns in csv file, forecasts starts with prefix “F_” followed by the name of corresponding actual, e.g. if historical actual is named “WindSpeed” then historical forecasts of the same predictor are named “F_WindSeed”. Since forecasts before the 2019-06-20 are not available we filled columns before the 2019-06-20 with 0. Columns with actuals are at the beginning of the file and columns with forecasts are at the end. (File location: Wind_portfolio/data.csv)

### Forecasting scenario¶

We simulate day ahead scenario. Each day at 21:35 we wish to have forecast for each hour of the next day. Last target value will be energy produced from 21:00 to 21:30 because data are already updated at 21:35. TIM convention is to denote interval 21:00 - 21:30 as 21:00. That means we have last timestamp from 21:00 (21:00 - 21:30) we are in half-hour 21:30 (21:30 – 22:00) and want forecast for each hour of the next day (day + 1). That means target availability is S-1 (sample - 1) and forecast horizon is from start of D+1 to the end of D+1 (day + 1). Meteo predictors will be available for every hour of our prediction.

### Model building and validation¶

Model is built using a range of 2018-01-01 00:00:00 - 2019-06-30 23:30:00.
Out-of-sample forecasts are made at range 2019-07-01 00:00:00 - 2019-08-15 23:30:00. In this demo data set, out-of-sample validation is performed using historical forecasts of meteorological data. Forecasts are stored in separate columns starting with “F_” followed by the name of corresponding actual predictor.

### Demonstration¶

#### TIM Studio¶

This section covers the use of TIM Studio to solve the challenge described above. Additional information regarding TIM Studio can be found here.

##### Select workspace¶

In the Workspaces screen, select the workspace in which the dataset should be added. If there is no available workspace, create one by clicking "Add Workspace". In this solution template, the workspace called "TIM Solution Templates" is used.

In the Datasets screen click on Add New Dataset. Stay in the tab CSV-File and insert name of the dataset. In this example, the dataset is called Wind_portfolio. Click "Browse" and select the dataset from the computer. Click "Add Dataset" to confirm.

##### Model building definition¶

Go to the Model Building Definition screen in the panel on the left. Click "Add New Definition" and fill in the desired definition name. In this demo, the MBD is called Wind_portfolio day-ahead. In the next screen, select the dataset that was previously uploaded (Wind_portfolio).

In step 2, define the desired forecasting scenario. In this example, the model is used each day at 21:35. Therefore, leave all "Weekdays ranges" checked on. Then, set "Hour ranges" to 21, "Minutes ranges" to 35 and leave "Seconds ranges" at 00. Look into the section about the Cron notation for more details. Since forecasts are to be made for each hour of the next day, leave default settings for "Forecast from" and "Forecast to", i.e. Day with offset 1. Look into the section about the relative time notation to learn more about this.

Click "Next" to advance to the next step. It is also possible to already finalize all settings at this point, in which case everything else would be set up automatically. In this example, some more changes will be made to the data updates in the third step. The target variable, Quantity, is updated at the fifth minute of each hour. Click on the small arrow next to Quantity and change the settings of this variable. Leave all "Weekdays ranges" checked on. Select "All" for the Hour, since this variable is updated each half-hour, and set the "Minutes ranges" to 5,35 since the data is updated in 5. and 35. minute of every hour. Leave the Second ranges at 0. Then, set "Update until" to Sample with offset -1, since the target variable is updated with a delay of one sample (in half-hour 21:30-22:00 only until 21:00 – 21:30).

Leave the default settings for all other predictors, i.e. they are set to update at 8:20 until Day+1. Since forecasts are made at 21:35 and forecasts of predictors values will be available for the next day, these default settings are alright; at what time they update exactly does not matter in this case.

Click "Next" to advance to step 4. Here, training regions can be selected. Since the goal is to move on to back-testing, this screen will be left in its default settings (i.e. Use All Data). Click "Next" to advance to the next screen.

In this fifth step, the mathematical settings can be changed. Weekdays will be switched off in TIM Transformations, since this dictionary) is not relevant for wind forecasting. Then, click "Finalize" to complete the model building definition.

##### Experiments¶

Click "Experiments" in the panel on the left to move on to backtesting. Then, click "Make experiment" next to the correct model building definition (Wind_portfolio day-ahead).

Click "Build Model" and select the appropriate training range, i.e. 2018-01-01 00:00:00 - 2019-06-30 23:30:00.

The in-sample prediction as well as the Model Tree Map become visible.

Click "Validate model" and select the correct Out-of-sample period for backtesting, i.e. 2019-07-01 00:00:00 - 2019-08-15 23:30:00.

This generates the aggregated forecasts for the day D+1.

#### TIM Connector¶

This section covers the use of TIM Connector to solve the challenge described above. Additional information regarding TIM Connector can be found in the respective section.

##### 2. Create folder with dataset¶

Create a folder e.g. TIM_Datasets, which contains dataset folder (Wind_portfolio) with dataset file [data.csv] and configuration file [conf.yaml].

TIM_Datasets/Wind_portfolio/ data.csv conf.yaml

The YAML configuration file defines the forecasting scenario described above.

Model building: Model building considers the range 2018-01-01 00:00:00- 2019-06-30 23:30:00. For model building are used columns 1-32 with timestamp, target and meteorological actuals. The target variable, Quantity, is updated with a delay of one sample (in half-hour 21:30-22:00 only until 21:00 – 21:30). It is updated at the fifth minute of each half-hour.

Configuration: The model is used repeatedly each day at 21:35. Forecasts are to be made for each hour of the next day. All features except calendar variables (WeekRest) are used; for more information about feature dictionaries take a look at the appropriate section.

Forecasting: Out-of-sample forecast are made on columns 1,2,33-62 i.e. time stamp, target and historical forecasts. Forecasts are made for the range 2019-07-01 00:00:00 - 2019-08-15 23:30:00.

version: "1.0"
type: Forecasting

modelBuilding:
data:
rows:
- from: 2018-01-01 00:00:00
to:   2019-06-30 23:30:00
columns: 1:32
- uniqueName: Quantity
updateUntil:
baseUnit: Sample
offset: -1
updateTime:
- type: Hour
value: "*"
- type: Minute
value: "05,35"

configuration:
usage:
usageType: Repeating
usageTime:
- type: Day
value: "*"
- type: Hour
value: "21"
- type: Minute
value: "35"
predictionFrom:
baseUnit: Day
offset: 1
predictionTo:
baseUnit: Day
offset: 1
features: [MovingAverage, Intercept, PiecewiseLinear, TimeOffsets, Polynomial, PeriodicComponents]

forecasting:
configuration:
data:
columns: 1:2,33:62
predictionScope:
type: Ranges
ranges:
- from: 2019-07-01 00:00:00
to:   2019-08-15 23:30:00

##### 3. Call connector from the command line¶

Using a terminal, change the current directory to TIM Connector's builddir with the command: > cd pathToConnector\builddir. Then, call the connector with the following command: > pathToConnector\timconnect.exe path\to\TIM_Datasets`.

##### 4. Fill in user credentials¶

Following the previous command, the user will be prompted to fill in their user credentials. Fill in the correct information and click "OK" to continue.

Output in console::

Output in folder: Predictions Report/timeStamp/conf/prediction.csv Errors Report/timeStamp/conf/accuracy.txt
The following accuracies were reported by TIM: Model building stage: RMSE = 749.27, MAE = 554.4
Validation stage: RMSE = 858.17, MAE = 678.86


text:
American Institute of Mathematical Sciences

• Previous Article
A hybrid particle swarm optimization and tabu search algorithm for order planning problems of steel factories based on the Make-To-Stock and Make-To-Order management architecture
• JIMO Home
• This Issue
• Next Article
On the admission control and demand management in a two-station tandem production system
January  2011, 7(1): 19-30. doi: 10.3934/jimo.2011.7.19

A queueing analysis of multi-purpose production facility's operations

 1 Saint Mary's University, Sobey School of Business, Department of Finance, Information Systems, and Management Science, Halifax, Nova Scotia, B3H 3C3, Canada 2 Western Washington University, College of Business and Economics, Department of Decision Sciences, Bellingham, WA 98225, United States 3 École de Technologie Supérieure, Département de Génie Électrique, Montréal, Québec, H3C 1K3, Canada

Received  July 2009 Revised  September 2010 Published  January 2011

In this paper, we study the production time allocation issue for a multi-purpose manufacturing facility. This production facility can produce different types of make-to-order and make-to-stock products. Using a vacation queueing model, we develop a set of quantitative performance measures for a two-parameter time allocation policy. Based on the renewal cycle analysis, we derive an average cost expression and propose a search algorithm to find the optimal time allocation policy that minimizes the average cost. Some numerical examples are presented to demonstrate the effectiveness of the search algorithm. The vacation model used in this paper is also a generalization of some previous vacation queueing models in the literature. The results obtained in this study are useful for production managers to design the operating policy in practice.
Citation: Lotfi Tadj, Zhe George Zhang, Chakib Tadj. A queueing analysis of multi-purpose production facility's operations. Journal of Industrial & Management Optimization, 2011, 7 (1) : 19-30. doi: 10.3934/jimo.2011.7.19
References:
 [1] L. Abolnikov and A. Dukhovny, Markov chains with transition delta-matrix: ergodicity conditions, invariant probability measures and applications,, Journal of Applied Mathematics and Stochastic Analysis, 4 (1991), 335.  doi: 10.1155/S1048953391000254.  Google Scholar [2] J. R. Artalejo and G. Choudhury, Steady state analysis of an M/G/1 queue with repeated attempts and two phase service,, Quality Technology and Quantitative Management, 1 (2004), 189.   Google Scholar [3] D. Bertsimas and X. Papaconstantinou, On the steady-state solution of the M/C$_2(a,b)$/$S$ queueing system,, Transportation Sciences, 22 (1988), 125.  doi: 10.1287/trsc.22.2.125.  Google Scholar [4] D. Bertsimas and X. Papaconstantinou, Analysis of the stationary $E_k$/$C_2$/S queueing system,, European Journal of Operational Research, 37 (1988), 272.  doi: 10.1016/0377-2217(88)90336-0.  Google Scholar [5] G. Choudhury, Some aspects of an M/G/1 queueing system with optional second service,, TOP, 11 (2003), 141.  doi: 10.1007/BF02578955.  Google Scholar [6] G. Choudhury and K. C. Madan, A two-phase batch arrival queueing system with a vacation time under Bernoulli schedule,, Applied Mathematics and Computation, 149 (2004), 337.  doi: 10.1016/S0096-3003(03)00138-3.  Google Scholar [7] G. Choudhury and K. C. Madan, A two-stage arrival queueing system with a modified Bernoulli schedule vacation under N-policy,, Mathematical and Computer Modelling, 42 (2005), 71.  doi: 10.1016/j.mcm.2005.04.003.  Google Scholar [8] G. Choudhury and M. Paul, A batch arrival queue with an additional service channel under N-policy,, Applied Mathematics and Computation, 156 (2004), 115.  doi: 10.1016/j.amc.2003.07.006.  Google Scholar [9] G. Choudhury and M. Paul, Analysis of a two phases batch arrival queueing model with Bernoulli vacation schedule,, Revista Investigatión Operacional, 25 (2004), 217.   Google Scholar [10] B. T. Doshi, Queueing systems with vacations: A survey,, Queueing Systems, 1 (1986), 29.  doi: 10.1007/BF01149327.  Google Scholar [11] B. T. Doshi, Single-server queues with vacations,, in, (1990), 217.   Google Scholar [12] B. T. Doshi, Analysis of a two-phase queueing system with general service times,, Operations Research Letters, 10 (1991), 265.  doi: 10.1016/0167-6377(91)90012-E.  Google Scholar [13] A. Federgruen and K. C. So, Optimality of threshold policies in single server queueing system with vacations,, Advances in Applied Probability, 23 (1991), 388.  doi: 10.2307/1427755.  Google Scholar [14] O. Kella, The threshold policy in the M/G/1 queue with server vacations,, Naval Research Logistics, 36 (1989), 111.  doi: 10.1002/1520-6750(198902)36:1<111::AID-NAV3220360109>3.0.CO;2-3.  Google Scholar [15] T. S. Kim and K. C. Chae, Two-phase queueing system with generalized vacation,, Journal of the Korean Institute of Industrial Engineers, 22 (1996), 95.   Google Scholar [16] T. S. Kim and A. Q. Park, Cycle analysis of a two-phase queueing model with threshold,, European Journal of Operational Research, 144 (2003), 157.   Google Scholar [17] C. M. Krishna and Y. H. Lee, A study of two-phase service,, Operations Research Letters, 9 (1990), 91.  doi: 10.1016/0167-6377(90)90047-9.  Google Scholar [18] H. W. Lee, S. S. Lee, J. O. Park and K. C. Chae, Analysis of M$^x$/G/1 queue with N policy and multiple vacations,, Journal of Applied Probability, 31 (1994), 467.  doi: 10.2307/3215040.  Google Scholar [19] K. C. Madan, A cyclic queueing system with three servers and optional two-way feedback,, Microelectron. Rel., 28 (1988), 873.  doi: 10.1016/0026-2714(88)90285-5.  Google Scholar [20] K. C. Madan, An M/G/1 queue with second optional service,, Queueing Systems, 34 (2000), 37.  doi: 10.1023/A:1019144716929.  Google Scholar [21] K. C. Madan, On a single server queue with two stage general heterogeneous service and binomial schedule server vacations,, The Egyptian Statistical Journal, 44 (2000), 39.   Google Scholar [22] K. C. Madan, On a single server queue with two stage general heterogeneous service and deterministic schedule server vacations,, International Journal of System Science, 32 (2001), 837.  doi: 10.1080/00207720121488.  Google Scholar [23] K. C. Madan and M. Al-Rawwash, On the M$^x$/G/1 queue with feedback and optional server vacations based on a single vacation policy,, Applied Mathematics and Computation, 160 (2005), 909.   Google Scholar [24] K. C. Madan and A. Z. Abu Al-Rub, On a single server queue with optional phase type server vacations based on exhaustive deterministic service and a single vacation policy,, Applied Mathematics and Computation, 149 (2004), 723.  doi: 10.1016/S0096-3003(03)00174-7.  Google Scholar [25] K. C. Madan, A. D. Al-Nasser and A. Q. Al-Masri, On M$^x$/(G1,G2)/1 queue with optional re-service,, Applied Mathematics and Computation, 152 (2004), 71.  doi: 10.1016/S0096-3003(03)00545-9.  Google Scholar [26] J. Medhi, A single server Poisson input queue with a second optional channel,, Queueing Systems, 42 (2002), 239.  doi: 10.1023/A:1020519830116.  Google Scholar [27] D. D. Selvam and V. Sivasankaran, A two-phase queueing system with server vacations,, Operations Research Letters, 15 (1994), 163.  doi: 10.1016/0167-6377(94)90052-3.  Google Scholar [28] L. Tadj and G. Choudhury, Optimal design and control of queues,, TOP, 13 (2005), 359.  doi: 10.1007/BF02579061.  Google Scholar [29] L. Tadj and J-.C. Ke, Control policy of a hysteretic queueing system,, Mathematical Methods of Operations Research, 57 (2003), 367.   Google Scholar [30] L. Tadj and J-.C. Ke, Control policy of a hysteretic bulk queueing system,, Mathematical and Computer Modelling, 5 (2004), 571.   Google Scholar [31] H. Takagi, "Queueing Analysis - A Foundation of Performance Evaluation,", Vol. 1, (1991).   Google Scholar [32] N. Tian and Z. G. Zhang, "Vacation Queueing Models - Theory and Applications,", Springer-Verlag, (2006).   Google Scholar [33] Z. G. Zhang, R. G. Vickson and M. J. A. van Eenige, Optimal two threshold policies in an M/G/1 queue with two vacation types,, Performance Evaluation, 29 (1997), 63.  doi: 10.1016/S0166-5316(96)00005-3.  Google Scholar [34] J. Wang, An M/G/1 queue with second optional service and server breakdowns,, Computers and Mathematics with Applications, 47 (2004), 1713.  doi: 10.1016/j.camwa.2004.06.024.  Google Scholar

show all references

References:
 [1] L. Abolnikov and A. Dukhovny, Markov chains with transition delta-matrix: ergodicity conditions, invariant probability measures and applications,, Journal of Applied Mathematics and Stochastic Analysis, 4 (1991), 335.  doi: 10.1155/S1048953391000254.  Google Scholar [2] J. R. Artalejo and G. Choudhury, Steady state analysis of an M/G/1 queue with repeated attempts and two phase service,, Quality Technology and Quantitative Management, 1 (2004), 189.   Google Scholar [3] D. Bertsimas and X. Papaconstantinou, On the steady-state solution of the M/C$_2(a,b)$/$S$ queueing system,, Transportation Sciences, 22 (1988), 125.  doi: 10.1287/trsc.22.2.125.  Google Scholar [4] D. Bertsimas and X. Papaconstantinou, Analysis of the stationary $E_k$/$C_2$/S queueing system,, European Journal of Operational Research, 37 (1988), 272.  doi: 10.1016/0377-2217(88)90336-0.  Google Scholar [5] G. Choudhury, Some aspects of an M/G/1 queueing system with optional second service,, TOP, 11 (2003), 141.  doi: 10.1007/BF02578955.  Google Scholar [6] G. Choudhury and K. C. Madan, A two-phase batch arrival queueing system with a vacation time under Bernoulli schedule,, Applied Mathematics and Computation, 149 (2004), 337.  doi: 10.1016/S0096-3003(03)00138-3.  Google Scholar [7] G. Choudhury and K. C. Madan, A two-stage arrival queueing system with a modified Bernoulli schedule vacation under N-policy,, Mathematical and Computer Modelling, 42 (2005), 71.  doi: 10.1016/j.mcm.2005.04.003.  Google Scholar [8] G. Choudhury and M. Paul, A batch arrival queue with an additional service channel under N-policy,, Applied Mathematics and Computation, 156 (2004), 115.  doi: 10.1016/j.amc.2003.07.006.  Google Scholar [9] G. Choudhury and M. Paul, Analysis of a two phases batch arrival queueing model with Bernoulli vacation schedule,, Revista Investigatión Operacional, 25 (2004), 217.   Google Scholar [10] B. T. Doshi, Queueing systems with vacations: A survey,, Queueing Systems, 1 (1986), 29.  doi: 10.1007/BF01149327.  Google Scholar [11] B. T. Doshi, Single-server queues with vacations,, in, (1990), 217.   Google Scholar [12] B. T. Doshi, Analysis of a two-phase queueing system with general service times,, Operations Research Letters, 10 (1991), 265.  doi: 10.1016/0167-6377(91)90012-E.  Google Scholar [13] A. Federgruen and K. C. So, Optimality of threshold policies in single server queueing system with vacations,, Advances in Applied Probability, 23 (1991), 388.  doi: 10.2307/1427755.  Google Scholar [14] O. Kella, The threshold policy in the M/G/1 queue with server vacations,, Naval Research Logistics, 36 (1989), 111.  doi: 10.1002/1520-6750(198902)36:1<111::AID-NAV3220360109>3.0.CO;2-3.  Google Scholar [15] T. S. Kim and K. C. Chae, Two-phase queueing system with generalized vacation,, Journal of the Korean Institute of Industrial Engineers, 22 (1996), 95.   Google Scholar [16] T. S. Kim and A. Q. Park, Cycle analysis of a two-phase queueing model with threshold,, European Journal of Operational Research, 144 (2003), 157.   Google Scholar [17] C. M. Krishna and Y. H. Lee, A study of two-phase service,, Operations Research Letters, 9 (1990), 91.  doi: 10.1016/0167-6377(90)90047-9.  Google Scholar [18] H. W. Lee, S. S. Lee, J. O. Park and K. C. Chae, Analysis of M$^x$/G/1 queue with N policy and multiple vacations,, Journal of Applied Probability, 31 (1994), 467.  doi: 10.2307/3215040.  Google Scholar [19] K. C. Madan, A cyclic queueing system with three servers and optional two-way feedback,, Microelectron. Rel., 28 (1988), 873.  doi: 10.1016/0026-2714(88)90285-5.  Google Scholar [20] K. C. Madan, An M/G/1 queue with second optional service,, Queueing Systems, 34 (2000), 37.  doi: 10.1023/A:1019144716929.  Google Scholar [21] K. C. Madan, On a single server queue with two stage general heterogeneous service and binomial schedule server vacations,, The Egyptian Statistical Journal, 44 (2000), 39.   Google Scholar [22] K. C. Madan, On a single server queue with two stage general heterogeneous service and deterministic schedule server vacations,, International Journal of System Science, 32 (2001), 837.  doi: 10.1080/00207720121488.  Google Scholar [23] K. C. Madan and M. Al-Rawwash, On the M$^x$/G/1 queue with feedback and optional server vacations based on a single vacation policy,, Applied Mathematics and Computation, 160 (2005), 909.   Google Scholar [24] K. C. Madan and A. Z. Abu Al-Rub, On a single server queue with optional phase type server vacations based on exhaustive deterministic service and a single vacation policy,, Applied Mathematics and Computation, 149 (2004), 723.  doi: 10.1016/S0096-3003(03)00174-7.  Google Scholar [25] K. C. Madan, A. D. Al-Nasser and A. Q. Al-Masri, On M$^x$/(G1,G2)/1 queue with optional re-service,, Applied Mathematics and Computation, 152 (2004), 71.  doi: 10.1016/S0096-3003(03)00545-9.  Google Scholar [26] J. Medhi, A single server Poisson input queue with a second optional channel,, Queueing Systems, 42 (2002), 239.  doi: 10.1023/A:1020519830116.  Google Scholar [27] D. D. Selvam and V. Sivasankaran, A two-phase queueing system with server vacations,, Operations Research Letters, 15 (1994), 163.  doi: 10.1016/0167-6377(94)90052-3.  Google Scholar [28] L. Tadj and G. Choudhury, Optimal design and control of queues,, TOP, 13 (2005), 359.  doi: 10.1007/BF02579061.  Google Scholar [29] L. Tadj and J-.C. Ke, Control policy of a hysteretic queueing system,, Mathematical Methods of Operations Research, 57 (2003), 367.   Google Scholar [30] L. Tadj and J-.C. Ke, Control policy of a hysteretic bulk queueing system,, Mathematical and Computer Modelling, 5 (2004), 571.   Google Scholar [31] H. Takagi, "Queueing Analysis - A Foundation of Performance Evaluation,", Vol. 1, (1991).   Google Scholar [32] N. Tian and Z. G. Zhang, "Vacation Queueing Models - Theory and Applications,", Springer-Verlag, (2006).   Google Scholar [33] Z. G. Zhang, R. G. Vickson and M. J. A. van Eenige, Optimal two threshold policies in an M/G/1 queue with two vacation types,, Performance Evaluation, 29 (1997), 63.  doi: 10.1016/S0166-5316(96)00005-3.  Google Scholar [34] J. Wang, An M/G/1 queue with second optional service and server breakdowns,, Computers and Mathematics with Applications, 47 (2004), 1713.  doi: 10.1016/j.camwa.2004.06.024.  Google Scholar
 [1] A. Azhagappan, T. Deepa. Transient analysis of N-policy queue with system disaster repair preventive maintenance re-service balking closedown and setup times. Journal of Industrial & Management Optimization, 2017, 13 (5) : 1-14. doi: 10.3934/jimo.2019083 [2] Pikkala Vijaya Laxmi, Singuluri Indira, Kanithi Jyothsna. Ant colony optimization for optimum service times in a Bernoulli schedule vacation interruption queue with balking and reneging. Journal of Industrial & Management Optimization, 2016, 12 (4) : 1199-1214. doi: 10.3934/jimo.2016.12.1199 [3] Gábor Horváth, Zsolt Saffer, Miklós Telek. Queue length analysis of a Markov-modulated vacation queue with dependent arrival and service processes and exhaustive service policy. Journal of Industrial & Management Optimization, 2017, 13 (3) : 1365-1381. doi: 10.3934/jimo.2016077 [4] Jing Shi, Tiaojun Xiao. Service investment and consumer returns policy in a vendor-managed inventory supply chain. Journal of Industrial & Management Optimization, 2015, 11 (2) : 439-459. doi: 10.3934/jimo.2015.11.439 [5] Bart Feyaerts, Stijn De Vuyst, Herwig Bruneel, Sabine Wittevrongel. The impact of the $NT$-policy on the behaviour of a discrete-time queue with general service times. Journal of Industrial & Management Optimization, 2014, 10 (1) : 131-149. doi: 10.3934/jimo.2014.10.131 [6] Peng Tong, Xiaogang Ma. Design of differentiated warranty coverage that considers usage rate and service option of consumers under 2D warranty policy. Journal of Industrial & Management Optimization, 2017, 13 (5) : 0-0. doi: 10.3934/jimo.2020035 [7] Kar Hung Wong, Yu Chung Eugene Lee, Heung Wing Joseph Lee, Chi Kin Chan. Optimal production schedule in a single-supplier multi-manufacturer supply chain involving time delays in both levels. Journal of Industrial & Management Optimization, 2018, 14 (3) : 877-894. doi: 10.3934/jimo.2017080 [8] Martin Bohner, Sabrina Streipert. Optimal harvesting policy for the Beverton--Holt model. Mathematical Biosciences & Engineering, 2016, 13 (4) : 673-695. doi: 10.3934/mbe.2016014 [9] Jianbin Li, Ruina Yang, Niu Yu. Optimal capacity reservation policy on innovative product. Journal of Industrial & Management Optimization, 2013, 9 (4) : 799-825. doi: 10.3934/jimo.2013.9.799 [10] Xiaoming Yan, Ping Cao, Minghui Zhang, Ke Liu. The optimal production and sales policy for a new product with negative word-of-mouth. Journal of Industrial & Management Optimization, 2011, 7 (1) : 117-137. doi: 10.3934/jimo.2011.7.117 [11] Jianxiong Zhang, Zhenyu Bai, Wansheng Tang. Optimal pricing policy for deteriorating items with preservation technology investment. Journal of Industrial & Management Optimization, 2014, 10 (4) : 1261-1277. doi: 10.3934/jimo.2014.10.1261 [12] John Leventides, Iraklis Kollias. Optimal control indicators for the assessment of the influence of government policy to business cycle shocks. Journal of Dynamics & Games, 2014, 1 (1) : 79-104. doi: 10.3934/jdg.2014.1.79 [13] C.E.M. Pearce, J. Piantadosi, P.G. Howlett. On an optimal control policy for stormwater management in two connected dams. Journal of Industrial & Management Optimization, 2007, 3 (2) : 313-320. doi: 10.3934/jimo.2007.3.313 [14] Veena Goswami, Gopinath Panda. Optimal information policy in discrete-time queues with strategic customers. Journal of Industrial & Management Optimization, 2019, 15 (2) : 689-703. doi: 10.3934/jimo.2018065 [15] Guodong Yi, Xiaohong Chen, Chunqiao Tan. Optimal pricing of perishable products with replenishment policy in the presence of strategic consumers. Journal of Industrial & Management Optimization, 2019, 15 (4) : 1579-1597. doi: 10.3934/jimo.2018112 [16] Yiling Chen, Baojun Bian. optimal investment and dividend policy in an insurance company: A varied bound for dividend rates. Discrete & Continuous Dynamical Systems - B, 2019, 24 (9) : 5083-5105. doi: 10.3934/dcdsb.2019044 [17] Yiling Chen, Baojun Bian. Optimal dividend policy in an insurance company with contagious arrivals of claims. Mathematical Control & Related Fields, 2019, 0 (0) : 0-0. doi: 10.3934/mcrf.2020024 [18] Zhijun Zhang. Optimal global asymptotic behavior of the solution to a singular monge-ampère equation. Communications on Pure & Applied Analysis, 2020, 19 (2) : 1129-1145. doi: 10.3934/cpaa.2020053 [19] Nikolai Dokuchaev. On strong causal binomial approximation for stochastic processes. Discrete & Continuous Dynamical Systems - B, 2014, 19 (6) : 1549-1562. doi: 10.3934/dcdsb.2014.19.1549 [20] Wai-Ki Ching, Sin-Man Choi, Min Huang. Optimal service capacity in a multiple-server queueing system: A game theory approach. Journal of Industrial & Management Optimization, 2010, 6 (1) : 73-102. doi: 10.3934/jimo.2010.6.73

2018 Impact Factor: 1.025

format: plain


text:
# Circuits Question -- Charging a car battery in 4 hours...

Tags:
1. Jan 18, 2016

### Kurtis McIntosh

1. The problem statement, all variables and given/known data
A constant current of 3A for 4 hours is required to charge an automotive battery. If the terminal voltage is 10 + 1/2 t V, where t is in hours,

(a) how much charge is transported as a result of the charging?
(b) how much energy is expended?
(c) how much does the charging cost? Assume electricity costs 9 cents/kWh.

2. Relevant equations
P = IV
q = dI/dt
P = dW/dt

3. The attempt at a solution
I originally thought I would need to convert the time into seconds to figure out the charge transported when solving for charge using an integral, the answer turned out to be right. However my problem comes to part b, and indirectly, c. When I was solving for work, I took the integral of power. I thought I needed to convert the voltage equation in terms of seconds so that's what I did. My answer was quite a ways off. Any help is appreciated.

2. Jan 18, 2016

### Staff: Mentor

Can you show your calculation details?

3. Jan 18, 2016

### Kurtis McIntosh

I'll try as best as I can using a computer.
(A) q(t) = int(3 dt) from 0 - 14400 s.
q(t) = 3t| from 0 - 14400 s
q(t) = 43.2 kC

(B) V = (10 + 1/2t) x (60 min/hr) x (60 sec/min) = 36000 + 1800t
P = IV = 3(36000 + 1800t) = 5400t + 108000
W = int(5400t + 108000 dt) from 0 - 14400s
W = 5.614e11 J.

The correct answer to part B should be 475.2 kJ

4. Jan 18, 2016

### Staff: Mentor

Note that the time conversion should not apply to the constant 10V term!. t is associated with only one term in the terminal voltage expression.

5. Jan 18, 2016

### Kurtis McIntosh

Ah I see, but where would I go from there? I feel like I'm still missing something since when using a similar form to the integral I have set up above. I still get answers that are to the 11th power of 10 versus where they should be around the 5th power of 10.

6. Jan 18, 2016

### Staff: Mentor

Do the integration using "4" as the upper limit for time. The result will be in V*A*hr (Volt Amp Hours):

$\int_0^4 (10 + \frac{1}{2} t) dt =~ ... VAhr$

You can do this because you're told that in the expression for the terminal voltage the time is specified in hours.

You can convert the resulting V*A*hr to V*A*sec afterwards.

7. Jan 18, 2016

### Kurtis McIntosh

Oh okay! I never thought of work as Volt*Amps*Second. That makes a lot of sense. Thanks!

8. Jan 19, 2016

### Staff: Mentor

I think you've noticed this isn't right?

9. Jan 19, 2016

### Staff: Mentor

Gaaah! I should have spotted that! Thanks for catching that.

10. Jan 19, 2016

### Kurtis McIntosh

That was a mistake haha. I know it should be I = dq/dt. My brain was just moving too quick for my fingers to comprehend and type the information!


text:
# Get rotation of object without decimals?

import bge
from bge import logic

from bge import logic
cont = logic.getCurrentController()
obj = cont.owner
rotation = obj.worldOrientation.to_euler()
print(rotation.x)
print(rotation.y)
print(rotation.z)

Here's my code (above), which works fine, but the console prints really long digits. I am trying to get an object to rotate according to another object's rotation by taking the objects rotation, comparing it to the other, and adding/subtraction to x, y, or z. The problem I have is that the rotations have decimals when they aren't supposed to (, or atleast I think). The object has 0, 0, 0 as its rotation when I go to the object panel, but if I add 10 degrees to z, the script will print a long number (10.01231234923) when I added 10 and only 10. The object is static. In other words, I dont need the small and specific value. How can I have it only print the whole number, i.e. without decimals? Thanks.

• What if you wrap it with round()? So print(round(rotation.x, 2)) where 2 is the number of decimal places to leave? – gandalf3 Nov 10 '15 at 1:42

round() the numbers before printing them:

print(round(rotation.x), round(rotation.y), round(rotation.z))

Blender uses radians natively for rotation. You see degrees in the panels because the default setting for Units under Scene properties is to show degrees.

There are only 2Pi radians in 360 degrees, hence 10 radians is more than a revolution. To add 10 degrees to a rotation use the radians(degrees) method. eg rot += radians(10)

You can use formatting when printing to reduce the amount of decimal places. %.0f prints a float (decimal) type with no decimal places. %5.2f is print a float in a 5 digit field with 2 decimal places.

import bge
from bge import logic
from math import degrees

cont = logic.getCurrentController()
obj = cont.owner
rotation = obj.worldOrientation.to_euler()

print("%.0f" % degrees(rotation.x))
print("%.0f" % degrees(rotation.y))
print("%.0f" % degrees(rotation.z))


text:
# Pressure is an isotropic normal stress, meaning that it acts perpendicularly to any chosen surface

1. Pressure is an isotropic normal stress, meaning that it acts perpendicularly to any chosen surface and has the same magnitude for all surfaces. Consider the stress tensor given here, which has only normal stress components. Is this stress tensor isotropic? The stress is in Pa.

5 0 0

n ˜ = 0 7 0

0 0 1

123

## Plagiarism Checker

Submit your documents and get free Plagiarism report

Free Plagiarism Checker


text:
# Summation of combinations [duplicate]

Possible Duplicate:
simple binomial theorem proof

Why is $${6\choose 0} + {7\choose 1} + \ldots + {n+6 \choose n} = {n+7 \choose n}\;?$$

-

## marked as duplicate by Mike Spivey, Micah, Alexander Gruber♦, draks ..., QiL Dec 14 '12 at 8:23

Write out ${n\choose k}$ for each term on the left-hand side and then combine. –  JohnD Dec 14 '12 at 4:42
What do you mean by combine? I thought you could only combine things with the same top number? –  Pam Dec 14 '12 at 4:42
Add up all of those binomial coefficients on the left-hand side. –  JohnD Dec 14 '12 at 4:43
6!/0!*6! + 7!/1!*6! + ... + (n+6)!/n!*6! = 1 + 7 + 28 + ... –  Pam Dec 14 '12 at 4:45
Hint for the algebraic argument: write $\binom{6}{0}$ as $\binom{7}{0}$ –  Isomorphism Dec 14 '12 at 4:56

HINTS: The algebraic argument is a proof by induction: verify the equality for $n=0$, and show that if $${6\choose 0} + {7\choose 1} + \ldots + {n+6 \choose n} = {n+7 \choose n}\;,$$ then $${6\choose 0} + {7\choose 1} + \ldots + {(n+1)+6 \choose {n+1}} = {(n+1)+7 \choose {n+1}}\;.$$ This is a pretty straightforward application of the Pascal’s triangle identity.

For the combinatorial argument, observe that $\binom{n+7}n=\binom{n+7}7$ is the number of ways to choose a $7$-element subset of $\{1,2,\dots,n+7\}$, and $\binom{k+6}k=\binom{k+6}6$ is the number of ways to choose a $7$-element subset of $\{1,\dots,n+7\}$ whose largest element is the number $k+1$. That is, to choose a $7$-element subset whose largest element is $10$, you first choose $10$, and then you have to choose $6$ of the numbers $\{1,\dots,9\}$.

-

The standard recursive formula for binomial coefficients is

$\binom{n}{k} = \binom{n-1}{k-1} + \binom{n-1}{k}$

There is a technique for recursion called "unrolling," where you repeatedly substitute a recurrence into its equation for itself. Here if we reverse the terms and then substitute repeatedly we get:

$\binom{n}{k} = \binom{n-1}{k} + \binom{n-1}{k-1}$

$\binom{n}{k} = \binom{n-1}{k} + \binom{n-2}{k-1} + \binom{n-2}{k-2}$

$\vdots$

$\binom{n}{k} = \binom{n-1}{k} + \binom{n-2}{k-1} + \binom{n-3}{k-2} + \cdots + \binom{n-k}{0}$

-
However, unrolling is not actually a proof; it’s one of the ways that one might discover the formula, and it suggests but does not actually incorporate the proof by induction. –  Brian M. Scott Dec 14 '12 at 5:01
This is true. The question said "show," and my assumption was that either the author did not need a proof or if she did she would have an idea of how to translate this into a proof. As you've pointed out, this should be done by induction. –  William Macrae Dec 14 '12 at 5:05
Show almost always means prove. –  Brian M. Scott Dec 14 '12 at 5:05
Although usually a "show" proof is less formal than a "prove" proof, in my experience. –  Joe Z. Dec 14 '12 at 5:31
@Joe: Some people do use the terms that way, but you can’t count on it: many of us use them completely synonymously. –  Brian M. Scott Dec 14 '12 at 6:42


text:
# Exponential Equations Reducible to Quadratic for Math Help

Exponential Equations Reducible to Quadratic for Math Help is based on various index rules, such as;
$$a^{x+y} = a^x \times a^y \\ (a^x)^y = a^{xy}$$

## Practice Questions of Exponential Equations Reducible to Quadratic

### Question 1

Solve $9^x – 10 \times 3^x + 9 = 0$.

### Question 2

Solve $4^x – 2^{x+2} -32 = 0$.

### Question 3

Solve $\displaystyle 3^{x^2-3x} = 81$.


text:
# How can I position a large amount of boxes to prevent overlap efficiently

I've been working on an asset to position labels like they do in Diablo or Path of Exile, but I'm having trouble finding an algorithm to position the labels efficiently.

Currently I just boxcast in each of the 4 directions until there is no overlap, compare their distances, and take the smallest value to place it, but this just seems too much hassle and too slow with a large number of labels.

Especially when you look at this video clip from Path of Exile without loot filter. There's no way they can iterate over that many labels and place them instantly.

I think they keep some kind of array that says "there are X open spots for this label group currently, select the nearest one or any", and update it when a label gets placed.

I know this question has been asked and I know about automatic label placement etc. but I don't think it really applies in this case. At a certain point it doesn't really matter where the labels get positioned, they just need to be positioned around another label as fast as possible without overlap.

Basically, I'm looking for a way to save occupied/unoccupied space around a label and retrieve that value somehow.

• "They just need to be positioned as fast as possible without overlap" - yes, that's exactly the problem that automatic label placement algorithms are designed to solve. Which ones have you tried implementing so far, and where did you run into trouble making them work for your needs? Jun 9, 2020 at 13:31
• I edited the question a bit cause the labels don't need to be placed randomly on the canvas anywhere, they still need to be connected to the group of labels as in next to, above or below a label. This is why I think the labeling alghoritms don't really apply and they do it differently in PoE.
– yean
Jun 9, 2020 at 14:09

Here's a sketch of one solution:

Divide your placement domain into rows, each row the height of a label. (If you have boxes of different vertical sizes this becomes more complicated, but it looks like the majority of items in Pillars of Eternity have very similar heights)

For each row, store a list of labels in that row. Each label knows its center, width, and the target point it's trying to align to.

This lets us greatly simplify the problem into finding a placement in a line, without hitting the full $$\n^2\$$ complexity of checking against every other label on screen.

When you add a new label, round its target point's vertical position divided by the row height to find which row it "wants" to be in.

Try first to place the label in this row.

With a linear or binary search, you can find the first label in the row that belongs to the right of this one / the last label that belongs to the left (based on their respective target positions). If there's no label that belongs to the left or right, you can treat those constraints as infinite.

Check if there's room to place the label between these limits - shifted to bring you as close as you can to your target position. If so, place the label, and you're done.

If not, compute the minimum penetration depth - how much would the other labels need to slide apart to make room? Hang onto that as a score for the disruptiveness of the placement.

Then check the row above/below in the same way, factoring in the vertical shift from where your label "wants" to be as part of their disruptiveness score. You can repeat this out to a controllable maximum vertical displacement. If you find a placement opportunity below a target disruptiveness score, place it. Otherwise, just pick the lowest score you found out of the rows you checked.

If your chosen placement requires sliding, you iterate over the other labels in the row to the left or right of your newly-placed label, shifting them over by the remaining overlap, until no overlap remains.

This approach is $$\O(r \cdot k)\$$ per insertion (or $$\O(r \cdot \log k + k)\$$ if you use binary search), where $$\k\$$ is the number of items in a single row (so, likely in the range of $$\k \approx \sqrt n\$$ where $$\n\$$ is the total number of labels on screen), and $$\r\$$ is the number of rows you check, which gives you a controllable trade-off between placement quality and search complexity. All the steps can be done with simple interval arithmetic, so you don't need to do any boxcasting along the way.


text:
## Precalculus (6th Edition) Blitzer

The given equation is a circle centered at the origin. Rotation of this equation with any angle will not change its form, which means we will get $(x')^2+(y')^2=r^2$ without even using the transformation formulas.


text:
# 3. Waf Tools

There are foxBMS 2 specific tools that do not come with waf by default. These tools are included in tools/waf-tools and implemented as Python scripts. The terms tool and script are used as synonyms in the following.

The function of each tool is described below.


text:
## Introduction¶

The EvMenu utility class is located in evennia/utils/evmenu.py. It allows for easily adding interactive menus to the game; for example to implement Character creation, building commands or similar. Below is an example of offering NPC conversation choices:

The guard looks at you suspiciously.
"No one is supposed to be in here ..."
he says, a hand on his weapon.
_______________________________________________
1. Try to bribe him [Cha + 10 gold]
2. Convince him you work here [Int]
3. Appeal to his vanity [Cha]
4. Try to knock him out [Luck + Dex]
5. Try to run away [Dex]

This is an example of a menu node. Think of a node as a point where the menu stops printing text and waits for user to give some input. By jumping to different nodes depending on the input, a menu is constructed.

## Ways to create the menu¶

### node functions¶

The native way to define an EvMenu is to define Python functions, one per node. It will load all those functions/nodes either from a module or by being passed a dictionary mapping the node’s names to said functions, like {"nodename": <function>, ...}. Since you are dealing with raw code, this is by far the most powerful way - for example you could have dynamic nodes that change content depending on game context, time and what you picked before.

Initializing the menu is done using a call to the evennia.utils.evmenu.EvMenu class. This is the most common way to do so - from inside a Command:

# in, for example gamedir/commands/command.py

key = "testcommand"

def func(self):

When running this command, the menu will start using the menu nodes loaded from mygame/world/mymenu.py and use this to build the menu-tree - each function name becomes the name of a node in the tree. See next section on how to define menu nodes.

"node1": nodefunc1,
"node2": nodefunc2,, ...}

   from evennia.utils.evmenu import parse_menu_template

The template_string and goto_callables are described in Template language section.

The EvMenu has the following optional callsign:

EvMenu(caller, menu_data,
startnode="start",
cmdset_mergetype="Replace", cmdset_priority=1,
auto_quit=True, auto_look=True, auto_help=True,
cmd_on_exit="look",
persistent=False,
startnode_input="",
session=None,
debug=False,
**kwargs)

• caller (Object or Account): is a reference to the object using the menu. This object will get a new CmdSet assigned to it, for handling the menu.

• menu_data (str, module or dict): is a module or python path to a module where the global-level functions will each be considered to be a menu node. Their names in the module will be the names by which they are referred to in the module. Importantly, function names starting with an underscore _ will be ignored by the loader. Alternatively, this can be a direct mapping {"nodename":function, ...}.

• startnode (str): is the name of the menu-node to start the menu at. Changing this means that you can jump into a menu tree at different positions depending on circumstance and thus possibly re-use menu entries.

• cmdset_mergetype (str): This is usually one of “Replace” or “Union” (see [CmdSets](Command- Sets). The first means that the menu is exclusive - the user has no access to any other commands while in the menu. The Union mergetype means the menu co-exists with previous commands (and may overload them, so be careful as to what to name your menu entries in this case).

• cmdset_priority (int): The priority with which to merge in the menu cmdset. This allows for advanced usage.

• auto_quit, auto_look, auto_help (bool): If either of these are True, the menu automatically makes a quit, look or help command available to the user. The main reason why you’d want to turn this off is if you want to use the aliases “q”, “l” or “h” for something in your menu. Nevertheless, at least quit is highly recommend - if False, the menu must itself supply an “exit node” (a node without any options), or the user will be stuck in the menu until the server reloads (or eternally if the menu is persistent)!

• cmd_on_exit (str): This command string will be executed right after the menu has closed down. From experience, it’s useful to trigger a “look” command to make sure the user is aware of the change of state; but any command can be used. If set to None, no command will be triggered after exiting the menu.

• persistent (bool) - if True, the menu will survive a reload (so the user will not be kicked out by the reload - make sure they can exit on their own!)

• startnode_input (str or (str, dict) tuple): Pass an input text or a input text + kwargs to the start node as if it was entered on a fictional previous node. This can be very useful in order to start a menu differently depending on the Command’s arguments in which it was initialized.

• session (Session): Useful when calling the menu from an Account in MULTISESSION_MODDE higher than 2, to make sure only the right Session sees the menu output.

• debug (bool): If set, the menudebug command will be made available in the menu. Use it to list the current state of the menu and use menudebug <variable> to inspect a specific state variable from the list.

• All other keyword arguments will be available as initial data for the nodes. They will be available in all nodes as properties on caller.ndb._menutree (see below). These will also survive a @reload if the menu is persistent.

You don’t need to store the EvMenu instance anywhere - the very act of initializing it will store it as caller.ndb._menutree on the caller. This object will be deleted automatically when the menu is exited and you can also use it to store your own temporary variables for access throughout the menu. Temporary variables you store on a persistent _menutree as it runs will not survive a @reload, only those you set as part of the original EvMenu call.

The EvMenu nodes consist of functions on one of these forms.

def menunodename1(caller):
# code
return text, options

# code
return text, options

# code
return text, options

While all of the above forms are okay, it’s recommended to stick to the third and last form since it gives the most flexibility. The previous forms are mainly there for backwards compatibility with existing menus from a time when EvMenu was less able.

### Input arguments to the node¶

• caller (Object or Account): The object using the menu - usually a Character but could also be a Session or Account depending on where the menu is used.

• raw_string (str): If this is given, it will be set to the exact text the user entered on the previous node (that is, the command entered to get to this node). On the starting-node of the menu, this will be an empty string, unless startnode_input was set.

• kwargs (dict): These extra keyword arguments are extra optional arguments passed to the node when the user makes a choice on the previous node. This may include things like status flags and details about which exact option was chosen (which can be impossible to determine from raw_string alone). Just what is passed in kwargs is up to you when you create the previous node.

### Return values from the node¶

Each function must return two variables, text and options.

#### text¶

The text variable is a string or tuple. This text is what will be displayed when the user reaches this node. If this is a tuple, then the first element of the tuple will be considered the displayed text and the second the help-text to display when the user enters the help command on this node.

    text = ("This is the text to display", "This is the help text for this node")

Returning a None text is allowed and simply leads to a node with no text and only options. If the help text is not given, the menu will give a generic error message when using help.

#### options¶

The options list describe all the choices available to the user when viewing this node. If options is returned as None, it means that this node is an Exit node - any text is displayed and then the menu immediately exits, running the exit_cmd if given.

Otherwise, options should be a list (or tuple) of dictionaries, one for each option. If only one option is available, a single dictionary can also be returned. This is how it could look:

def node_test(caller, raw_string, **kwargs):

text = "A goblin attacks you!"

options = (
{"key": ("Attack", "a", "att"),
"desc": "Strike the enemy with all your might",
"goto": "node_attack"},
{"key": ("Defend", "d", "def"),
"desc": "Hold back and defend yourself",
"goto": (_defend, {"str": 10, "enemyname": "Goblin"})})

return text, options

This will produce a menu node looking like this:

A goblin attacks you!
________________________________

Attack: Strike the enemy with all your might
Defend: Hold back and defend yourself

##### option-key ‘key’¶

The option’s key is what the user should enter in order to choose that option. If given as a tuple, the first string of that tuple will be what is shown on-screen while the rest are aliases for picking that option. In the above example, the user could enter “Attack” (or “attack”, it’s not case-sensitive), “a” or “att” in order to attack the goblin. Aliasing is useful for adding custom coloring to the choice. The first element of the aliasing tuple should then be the colored version, followed by a version without color - since otherwise the user would have to enter the color codes to select that choice.

Note that the key is optional. If no key is given, it will instead automatically be replaced with a running number starting from 1. If removing the key part of each option, the resulting menu node would look like this instead:

A goblin attacks you!
________________________________

1: Strike the enemy with all your might
2: Hold back and defend yourself

Whether you want to use a key or rely on numbers is mostly a matter of style and the type of menu.

EvMenu accepts one important special key given only as "_default". This key is used when a user enters something that does not match any other fixed keys. It is particularly useful for getting user input:

def node_readuser(caller, raw_string, **kwargs):

options = {"key": "_default",
"goto": "node_parse_input"}

return text, options

A "_default" option does not show up in the menu, so the above will just be a node saying "Please enter your name". The name they entered will appear as raw_string in the next node.

#### option-key ‘desc’¶

This simply contains the description as to what happens when selecting the menu option. For "_default" options or if the key is already long or descriptive, it is not strictly needed. But usually it’s better to keep the key short and put more detail in desc.

#### option-key ‘goto’¶

This is the operational part of the option and fires only when the user chooses said option. Here are three ways to write it

def _action_two(caller, raw_string, **kwargs):
# do things ...
return "calculated_node_to_go_to"

def _action_three(caller, raw_string, **kwargs):
# do things ...
return "node_four", {"mode": 4}

def node_select(caller, raw_string, **kwargs):

text = ("select one",
"help - they all do different things ...")

options = ({"desc": "Option one",
"goto": "node_one"},
{"desc": "Option two",
"goto": _action_two},
{"desc": "Option three",
"goto": (_action_three, {"key": 1, "key2": 2})}
)

return text, options

As seen above, goto could just be pointing to a single nodename string - the name of the node to go to. When given like this, EvMenu will look for a node named like this and call its associated function as

    nodename(caller, raw_string, **kwargs)

Here, raw_string is always the input the user entered to make that choice and kwargs are the same as those kwargs that already entered the current node (they are passed on).

Alternatively the goto could point to a “goto-callable”. Such callables are usually defined in the same module as the menu nodes and given names starting with _ (to avoid being parsed as nodes themselves). These callables will be called the same as a node function - callable(caller, raw_string, **kwargs), where raw_string is what the user entered on this node and **kwargs is forwarded from the node’s own input.

The goto option key could also point to a tuple (callable, kwargs) - this allows for customizing the kwargs passed into the goto-callable, for example you could use the same callable but change the kwargs passed into it depending on which option was actually chosen.

The “goto callable” must either return a string "nodename" or a tuple ("nodename", mykwargs). This will lead to the next node being called as either nodename(caller, raw_string, **kwargs) or nodename(caller, raw_string, **mykwargs) - so this allows changing (or replacing) the options going into the next node depending on what option was chosen.

There is one important case - if the goto-callable returns None for a nodename, the current node will run again, possibly with different kwargs. This makes it very easy to re-use a node over and over, for example allowing different options to update some text form being passed and manipulated for every iteration.

The EvMenu also supports the exec option key. This allows for running a callable before the goto-callable. This functionality comes from a time before goto could be a callable and is deprecated as of Evennia 0.8. Use goto for all functionality where you’d before use exec.

## Temporary storage¶

When the menu starts, the EvMenu instance is stored on the caller as caller.ndb._menutree. Through this object you can in principle reach the menu’s internal state if you know what you are doing. This is also a good place to store temporary, more global variables that may be cumbersome to keep passing from node to node via the **kwargs. The _menutree will be deleted automatically when the menu closes, meaning you don’t need to worry about cleaning anything up.

If you want permanent state storage, it’s instead better to use an Attribute on caller. Remember that this will remain after the menu closes though, so you need to handle any needed cleanup yourself.

The EvMenu display of nodes, options etc are controlled by a series of formatting methods on the EvMenu class. To customize these, simply create a new child class of EvMenu and override as needed. Here is an example:

from evennia.utils.evmenu import EvMenu

def nodetext_formatter(self, nodetext):
"""
Format the node text itself.

Args:
nodetext (str): The full node text (the text describing the node).

Returns:
nodetext (str): The formatted node text.

"""

def helptext_formatter(self, helptext):
"""
Format the node's help text

Args:
helptext (str): The unformatted help text for the node.

Returns:
helptext (str): The formatted help text.

"""

def options_formatter(self, optionlist):
"""
Formats the option block.

Args:
optionlist (list): List of (key, description) tuples for every
option related to this node.
caller (Object, Account or None, optional): The caller of the node.

Returns:
options (str): The formatted option display.

"""

def node_formatter(self, nodetext, optionstext):
"""
Formats the entirety of the node.

Args:
nodetext (str): The node text as returned by self.nodetext_formatter.
optionstext (str): The options display as returned by self.options_formatter.
caller (Object, Account or None, optional): The caller of the node.

Returns:
node (str): The formatted node to display.

"""

See evennia/utils/evmenu.py for the details of their default implementations.

The EvMenu is very powerful and flexible. But often your menu is simple enough to not require the full power of EvMenu. For this you can use the Evmenu templating language.

This is how the templating is used:

from evennia.utils.evmenu import parse_menu_template, EvMenu

template_string = "(will be described below)"
# this could be empty if you don't need to access any callables
goto_callables = {"mycallable1": function, ...}

… So the parse_menu_template is just another way to generate the menutree dict needed by EvMenu - after this EvMenu works normally.

The good thing with this two-step procedude is that you can mix- and match - if you wanted you could insert a normal, fully flexible function-based node-function in the menutree before passing the whole thing into EvMenu and get the best of both worlds. It also makes it easy to substitute base EvMenu with a child class that changes the menu display.

… But if you really don’t need any such customization, you can also apply the template in one step using the template2menu helper:

from evennia.utils.evmenu import template2menu

template_string = "(will be described below)"
goto_callables = {"mycallable1": function, ...}

In addition to the template-related arguments, template2menu takes all the same **kwargs as EvMenu and will parse the template and start the menu for you in one go.

### The templating string¶

The template is a normal string with a very simple format. Each node begins with a marker ## Node <name of node>, follwowed by a ## Options separator (the Node and Options are case-insensitive).

template_string = """

## NODE start

<text for the node>

## OPTIONS

# this is a comment. Only line-comments are allowed.

key;alias;alias: description -> goto_str_or_callable
key;alias;alias: goto_str_or_callable
>pattern: goto_str_or_callable

"""

• The text after ## NODE defines the name of the node. This must be unique within the menu because this is what you use for goto statements. The name could have spaces.

• The area between ## NODE and ## OPTIONS contains the text of the node. It can have normal formatting and will retain intentation.

• The ## OPTIONS section, until the next ## NODE or the end of the string, holds the options, one per line.

• Option-indenting is ignored but can be useful for readability.

• The options-section can also have line-comments, marked by starting the line with #.

• A node without a following ## OPTIONS section indicates an end node, and reaching it will print the text and immediately exit the menu (same as for regular EvMenu).

### Templating options format¶

The normal, full syntax is:

key;alias;alias: description -> goto_str_or_callable

An example would be

next;n: Go to node Two -> node2

In the menu, this will become an option

next: Go to node Two

where you can enter next or n to go to the menu node named node2.

To skip the description, just add the goto without the ->:

next;n: node2

This will create a menu option without any description:

next

A special key is >. This acts as a pattern matcher. Between > and the : one can fit an optional pattern. This pattern will first be parsed with glob-style parsing and then with regex, and only if the player’s input matches either will the option be chosen. An input-matching option cannot have a description.

  # this matches the empty string (just pressing return)
>: node2

# this matches input starting with 'test' (regex match)
> ^test.+?: testnode

# this matches any number input (regex match)
> [0-9]+?: countnode

# this matches everything not covered by previous options
# (glob-matching, space is stripped without quotes)
> *: node3

You can have multiple pattern-matchers for a node but remember that options are checked in the order they are listed. So make sure to put your pattern-matchers in decending order of generality; if you have a ‘catch-all’ pattern, it should be put last or those behind it will never be tried.

   next;n: node2
back;b: node1
>: node2

The above would give you the option to write next/back but you can also just press return to move on to the next node.

### Templating goto-callables¶

Instead of giving the name of a node to go to, you can also give the name of a goto_callable, which in turn returns the name of the node to go to. You tell the template it’s a callable by simply adding () at the end.

next: Go to node 2 -> goto_node2()

You can also add keyword arguments:

back: myfunction(from=foo)

Note: ONLY keyword-arguments are supported! Trying to pass a positional argument will lead to an error.

The contents of the kwargs-values will be evaluated by literal_eval so you don’t need to add quotes to strings unless they have spaces in them. Numbers will be converted correctly, but more complex input structures (like lists or dicts) will not - if you want more complex input you should use a full function-based EvMenu node instead.

The goto-callable is defined just like any Evmenu goto-func. You must always use the full form (including **kwargs):

def mygotocallable(caller, raw_string, **kwargs):
# ...
return "nodename_to_goto"

Return None to re-run the current node. Any keyword arguments you specify in your template will be passed to your goto-callable in **kwargs. Unlike in regular EvMenu nodes you can’t return kwargs to pass it between nodes and other dynamic tricks.

All goto-callables you use in your menu-template must be added to the goto_callable mapping that you pass to parse_menu_template or template2menu.

### Templating example to show all possible options:¶

template_string = """

## NODE start

This is the text of the start node.
Both ## NODE, ## node or ## Node works. The node-name can have
spaces.

The text area can have multiple lines, line breaks etc.

## OPTIONS

# here starts the option-defition
# comments are only allowed from beginning of line.
# Indenting is not necessary, but good for readability

1: Option number 1 -> node1
2: Option number 2 -> node2
next: This steps next -> go_back()
# the -> can be ignored if there is no desc
back: go_back(from_node=start)
abort: abort

# ----------------------------------- this is ignored

## NODE node1

Text for Node1. Enter a message!
<return> to go back.

## options

# Starting the option-line with >
# allows to perform different actions depending on
# what is inserted.

# this catches everything starting with foo
> foo*: handle_foo_message()

# regex are also allowed (this catches number inputs)
> [0-9]+?: handle_numbers()

# this catches the empty return
>: start

# this catches everything else
> *: handle_message(from_node=node1)

# -----------------------------------------

## NODE node2

Text for Node2. Just go back.

## options

>: start

# node abort

This exits the menu since there is no ## options section.

"""

# we assume the callables are defined earlier
goto_callables = {"go_back": go_back_func,
"handle_foo_message": handle_message,
"handle_numbers": my_number_handler,
"handle_message": handle_message2}

## Examples:¶

Below is an example of a simple branching menu node leading to different other nodes depending on choice:

# in mygame/world/mychargen.py

def define_character(caller):
text = \
"""
What aspect of your character do you want
to change next?
"""
options = ({"desc": "Change the name",
"goto": "set_name"},
{"desc": "Change the description",
"goto": "set_description"})
return text, options

This will result in the following node display:

What aspect of your character do you want
to change next?
_________________________
1: Change the name
2: Change the description

Note that since we didn’t specify the “name” key, EvMenu will let the user enter numbers instead. In the following examples we will not include the EvMenu call but just show nodes running inside the menu. Also, since EvMenu also takes a dictionary to describe the menu, we could have called it like this instead in the example:

EvMenu(caller, {"define_character": define_character}, startnode="define_character")

### Example: Dynamic goto¶

def _is_in_mage_guild(caller, raw_string, **kwargs):
if caller.tags.get('mage', category="guild_member"):
return "mage_guild_welcome"
else:
return "mage_guild_blocked"

def enter_guild:
text = 'You say to the mage guard:'
options ({'desc': 'I need to get in there.',
'goto': _is_in_mage_guild},
{'desc': 'Never mind',
'goto': 'end_conversation'})
return text, options

This simple callable goto will analyse what happens depending on who the caller is. The enter_guild node will give you a choice of what to say to the guard. If you try to enter, you will end up in different nodes depending on (in this example) if you have the right Tag set on yourself or not. Note that since we don’t include any ‘key’s in the option dictionary, you will just get to pick between numbers.

### Example: Set caller properties¶

Here is an example of passing arguments into the goto callable and use that to influence which node it should go to next:

def _set_attribute(caller, raw_string, **kwargs):
"Get which attribute to modify and set it"

attrname, value = kwargs.get("attr", (None, None))
next_node = kwargs.get("next_node")

return next_node

def node_background(caller):
text = \
"""
{} experienced a traumatic event
in their childhood. What was it?
""".format(caller.key}

options = ({"key": "death",
"desc": "A violent death in the family",
"goto": (_set_attribute, {"attr": ("experienced_violence", True),
"next_node": "node_violent_background"})},
{"key": "betrayal",
"desc": "The betrayal of a trusted grown-up",
"goto": (_set_attribute, {"attr": ("experienced_betrayal", True),
"next_node": "node_betrayal_background"})})
return text, options

This will give the following output:

Kovash the magnificent experienced a traumatic event
in their childhood. What was it?
____________________________________________________
death: A violent death in the family
betrayal: The betrayal of a trusted grown-up

Note above how we use the _set_attribute helper function to set the attribute depending on the User’s choice. In thie case the helper function doesn’t know anything about what node called it - we even tell it which nodename it should return, so the choices leads to different paths in the menu. We could also imagine the helper function analyzing what other choices

### Example: Get arbitrary input¶

An example of the menu asking the user for input - any input.

def _set_name(caller, raw_string, **kwargs):

inp = raw_string.strip()

prev_entry = kwargs.get("prev_entry")

if not inp:
# a blank input either means OK or Abort
if prev_entry:
caller.key = prev_entry
caller.msg("Set name to {}.".format(prev_entry))
return "node_background"
else:
caller.msg("Aborted.")
return "node_exit"
else:
# re-run old node, but pass in the name given
return None, {"prev_entry": inp}

def enter_name(caller, raw_string, **kwargs):

# check if we already entered a name before
prev_entry = kwargs.get("prev_entry")

if prev_entry:
text = "Current name: {}.\nEnter another name or <return> to accept."
else:
text = "Enter your character's name or <return> to abort."

options = {"key": "_default",
"goto": (_set_name, {"prev_entry": prev_entry})}

return text, options

This will display as

Enter your character's name or <return> to abort.

> Gandalf

Current name: Gandalf
Enter another name or <return> to accept.

>

Set name to Gandalf.

Here we re-use the same node twice for reading the input data from the user. Whatever we enter will be caught by the _default option and passed into the helper function. We also pass along whatever name we have entered before. This allows us to react correctly on an “empty” input - continue to the node named "node_background" if we accept the input or go to an exit node if we presses Return without entering anything. By returning None from the helper function we automatically re-run the previous node, but updating its ingoing kwargs to tell it to display a different text.

### Example: Storing data between nodes¶

A convenient way to store data is to store it on the caller.ndb._menutree which you can reach from every node. The advantage of doing this is that the _menutree NAttribute will be deleted automatically when you exit the menu.

def _set_name(caller, raw_string, **kwargs):

caller.msg("You set your name to {}".format(raw_string)
return "background"

def node_set_name(caller):
options = {'key': '_default',
'goto': _set_name}

return text, options

...

def node_view_sheet(caller):

options = ({"key": "Accept",
"goto": "finish_chargen"},
{"key": "Decline",
"goto": "start_over"})

return text, options

Instead of passing the character sheet along from node to node through the kwargs we instead set it up temporarily on caller.ndb._menutree.charactersheet. This makes it easy to reach from all nodes. At the end we look at it and, if we accept the character the menu will likely save the result to permanent storage and exit.

One point to remember though is that storage on caller.ndb._menutree is not persistent across @reloads. If you are using a persistent menu (using EvMenu(..., persistent=True) you should use caller.db to store in-menu data like this as well. You must then yourself make sure to clean it when the user exits the menu.

### Example: Repeating the same node¶

Sometimes you want to make a chain of menu nodes one after another, but you don’t want the user to be able to continue to the next node until you have verified that what they input in the previous node is ok. A common example is a login menu:

# re-run current node by returning None
return None
else:
# username ok - continue to next node

options = {"key": "_default",
return text, options

nattempts = kwargs.get("nattempts", 0)
if nattempts > 3:
caller.msg("Too many failed attempts. Logging out")
return "node_abort"
return None, {"nattempts", nattempts + 1}
else:

options = {"key": "_default",
return text, options

This will display something like

---------------------------
---------------------------

> Fo

------------------------------
______________________________
abort: (back to start)
------------------------------

> Foo

---------------------------
---------------------------

> Bar

--------------------------
--------------------------

And so on.

Here the goto-callables will return to the previous node if there is an error. In the case of password attempts, this will tick up the nattempts argument that will get passed on from iteration to iteration until too many attempts have been made.

### Defining nodes in a dictionary¶

You can also define your nodes directly in a dictionary to feed into the EvMenu creator.

def mynode(caller):
# a normal menu node function
return text, options

"node2": lambda caller: (
"This is the node text",
({"key": "lambda node 1",
"desc": "go to node 1 (mynode)",
"goto": "node1"},
{"key": "lambda node 2",
"desc": "go to thirdnode",
"goto": "node3"})),
"node3": lambda caller, raw_string: (
# ... etc ) }

# start menu, assuming 'caller' is available from earlier

The keys of the dictionary become the node identifiers. You can use any callable on the right form to describe each node. If you use Python lambda expressions you can make nodes really on the fly. If you do, the lambda expression must accept one or two arguments and always return a tuple with two elements (the text of the node and its options), same as any menu node function.

Creating menus like this is one way to present a menu that changes with the circumstances - you could for example remove or add nodes before launching the menu depending on some criteria. The drawback is that a lambda expression is much more limited than a full function - for example you can’t use other Python keywords like if inside the body of the lambda.

Unless you are dealing with a relatively simple dynamic menu, defining menus with lambda’s is probably more work than it’s worth: You can create dynamic menus by instead making each node function more clever. See the NPC shop tutorial for an example of this.

This describes two ways for asking for simple questions from the user. Using Python’s input will not work in Evennia. input will block the entire server for everyone until that one player has entered their text, which is not what you want.

### The yield way¶

In the func method of your Commands (only) you can use Python’s built-in yield command to request input in a similar way to input. It looks like this:

result = yield("Please enter your answer:")

This will send “Please enter your answer” to the Command’s self.caller and then pause at that point. All other players at the server will be unaffected. Once caller enteres a reply, the code execution will continue and you can do stuff with the result. Here is an example:

from evennia import Command
class CmdTestInput(Command):
key = "test"
def func(self):
self.caller.msg(f"You entered {result}.")
result2 = yield("Now enter something else:")
self.caller.msg(f"You now entered {result2}.")

Using yield is simple and intuitive, but it will only access input from self.caller and you cannot abort or time out the pause until the player has responded. Under the hood, it is actually just a wrapper calling get_input described in the following section.

Important Note: In Python you cannot mix yield and return <value> in the same method. It has to do with yield turning the method into a generator. A return without an argument works, you can just not do return <value>. This is usually not something you need to do in func() anyway, but worth keeping in mind.

### The get_input way¶

The evmenu module offers a helper function named get_input. This is wrapped by the yield statement which is often easier and more intuitive to use. But get_input offers more flexibility and power if you need it. While in the same module as EvMenu, get_input is technically unrelated to it. The get_input allows you to ask and receive simple one-line input from the user without launching the full power of a menu to do so. To use, call get_input like this:

get_input(caller, prompt, callback)

Here caller is the entity that should receive the prompt for input given as prompt. The callback is a callable function(caller, prompt, user_input) that you define to handle the answer from the user. When run, the caller will see prompt appear on their screens and any text they enter will be sent into the callback for whatever processing you want.

Below is a fully explained callback and example call:

from evennia import Command

def callback(caller, prompt, user_input):
"""
This is a callback you define yourself.

Args:
caller (Account or Object): The one being asked
for input
prompt (str): A copy of the current prompt
user_input (str): The input from the account.

Returns:
repeat (bool): If not set or False, exit the
input prompt and clean up. If returning anything
True, stay in the prompt, which means this callback
will be called again with the next user input.
"""

get_input(caller, "Write something! ", callback)

This will show as

Write something!
> Hello

Normally, the get_input function quits after any input, but as seen in the example docs, you could return True from the callback to repeat the prompt until you pass whatever check you want.

Note: You cannot link consecutive questions by putting a new get_input call inside the callback. If you want that you should use an EvMenu instead (see the Repeating the same node example above). Otherwise you can either peek at the implementation of get_input and implement your own mechanism (it’s just using cmdset nesting) or you can look at this extension suggested on the mailing list.

#### Example: Yes/No prompt¶

Below is an example of a Yes/No prompt using the get_input function:

def yesno(caller, prompt, result):
if result.lower() in ("y", "yes", "n", "no"):
# do stuff to handle the yes/no answer
# ...
# if we return None/False the prompt state
# will quit after this
else:
# the answer is not on the right yes/no form
@        # returning True will make sure the prompt state is not exited
return True

get_input(caller, "Is Evennia great (Yes/No)?", yesno)

## The @list_node decorator¶

The evennia.utils.evmenu.list_node is an advanced decorator for use with EvMenu node functions. It is used to quickly create menus for manipulating large numbers of items.

text here
______________________________________________

1. option1     7. option7      13. option13
2. option2     8. option8      14. option14
3. option3     9. option9      [p]revius page
4. option4    10. option10      page 2
5. option5    11. option11     [n]ext page
6. option6    12. option12

The menu will automatically create an multi-page option listing that one can flip through. One can inpect each entry and then select them with prev/next. This is how it is used:

from evennia.utils.evmenu import list_node

...

_options(caller):
return ['option1', 'option2', ... 'option100']

# analyze choice
return node_matching_the_choice

@list_node(_options, select=_select, pagesize=10)
def node_mylist(caller, raw_string, **kwargs):
...

# the decorator auto-creates the options; any options
# returned here would be appended to the auto-options
return node_text, {}

The options argument to list_node is either a list, a generator or a callable returning a list of strings for each option that should be displayed in the node.

The select is a callable in the example above but could also be the name of a menu node. If a callable, the menuchoice argument holds the selection done and available_choices holds all the options available. The callable should return the menu to go to depending on the selection (or None to rerun the same node). If the name of a menu node, the selection will be passed as selection kwarg to that node.

The decorated node itself should return text to display in the node. It must return at least an empty dictionary for its options. It returning options, those will supplement the options auto-created by the list_node decorator.

## Assorted notes¶

The EvMenu is implemented using Commands. When you start a new EvMenu, the user of the menu will be assigned a CmdSet with the commands they need to navigate the menu. This means that if you were to, from inside the menu, assign a new command set to the caller, you may override the Menu Cmdset and kill the menu. If you want to assign cmdsets to the caller as part of the menu, you should store the cmdset on caller.ndb._menutree and wait to actually assign it until the exit node.


text:
Stream: new members

Topic: proving simple inductive types are decidably equal

Edward Ayers (Nov 06 2018 at 15:08):

Suppose I make

inductive foo |A |B |C |D |E

How can I show thatfoo is decidably equal with minimal faff?

Floris van Doorn (Nov 06 2018 at 15:10):

@[derive decidable_eq] inductive foo |A |B |C |D |E

win for Lean

Edward Ayers (Nov 06 2018 at 15:10):

What else can I @[derive ...]?

Floris van Doorn (Nov 06 2018 at 15:12):

Not sure. In mathlib, if I search for derive, I only find derive decidable_eq and derive has_reflect.

Edward Ayers (Nov 06 2018 at 15:12):

I found has_sizeof in the wild

Scott Morrison (Nov 06 2018 at 21:26):

I would love to write some "functorial" derive handlers, for automatically showing constructions are functorial with respect to either morphisms in their arguments, or isomorphisms in their arguments. This would be part of a bigger program to do transport of structure.

Patrick Massot (Nov 06 2018 at 21:31):

Today Cyril worked quite a lot on transport stuff.

Scott Morrison (Nov 06 2018 at 21:52):

Ah, okay, what approach are they taking?

Patrick Massot (Nov 06 2018 at 21:53):

https://hal.inria.fr/hal-01559073

Scott Morrison (Nov 06 2018 at 21:55):

I would really like some feedback on my iso_induction approach sketched in the comments of https://github.com/leanprover/mathlib/issues/408, and the very initial branch at https://github.com/leanprover-community/mathlib/commit/fc31a8c81040f2a7e087df890f1c848ff6d34eff.

It needs more examples of definitions shown to be functorial in their arguments (hopefully automatically) before you can really see how it would work.

Last updated: May 13 2021 at 21:12 UTC